﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using com.lover.astd.common.model;
using com.lover.astd.common.model.enumer;

namespace com.lover.astd.common.logic
{
    public class ActivityMgr : MgrBase
    {
        public ActivityMgr() { _logColor = System.Drawing.Color.SteelBlue; }

        #region silver flop
        private bool doSilverFlopStep(char[,] s, int pos)
        {
            if (pos == 0) return false;
            char tmp;
            switch (pos)
            {
                case 12:
                    if (s[0, 0] == s[1, 0] && s[0, 0] == s[2, 0]) return false;
                    tmp = s[0, 0];
                    s[0, 0] = s[1, 0];
                    s[1, 0] = s[2, 0];
                    s[2, 0] = tmp;
                    break;
                case 11:
                    if (s[0, 1] == s[1, 1] && s[0, 1] == s[2, 1]) return false;
                    tmp = s[0, 1];
                    s[0, 1] = s[1, 1];
                    s[1, 1] = s[2, 1];
                    s[2, 1] = tmp;
                    break;
                case 10:
                    if (s[0, 2] == s[1, 2] && s[0, 2] == s[2, 2]) return false;
                    tmp = s[0, 2];
                    s[0, 2] = s[1, 2];
                    s[1, 2] = s[2, 2];
                    s[2, 2] = tmp;
                    break;
                case 9:
                    if (s[0, 2] == s[0, 1] && s[0, 2] == s[0, 0]) return false;
                    tmp = s[0, 2];
                    s[0, 2] = s[0, 1];
                    s[0, 1] = s[0, 0];
                    s[0, 0] = tmp;
                    break;
                case 8:
                    if (s[1, 2] == s[1, 1] && s[1, 2] == s[1, 0]) return false;
                    tmp = s[1, 2];
                    s[1, 2] = s[1, 1];
                    s[1, 1] = s[1, 0];
                    s[1, 0] = tmp;
                    break;
                case 7:
                    if (s[2, 2] == s[2, 1] && s[2, 2] == s[2, 0]) return false;
                    tmp = s[2, 2];
                    s[2, 2] = s[2, 1];
                    s[2, 1] = s[2, 0];
                    s[2, 0] = tmp;
                    break;
                case 6:
                    if (s[0, 2] == s[1, 2] && s[0, 2] == s[2, 2]) return false;
                    tmp = s[2, 2];
                    s[2, 2] = s[1, 2];
                    s[1, 2] = s[0, 2];
                    s[0, 2] = tmp;
                    break;
                case 5:
                    if (s[0, 1] == s[1, 1] && s[0, 1] == s[2, 1]) return false;
                    tmp = s[2, 1];
                    s[2, 1] = s[1, 1];
                    s[1, 1] = s[0, 1];
                    s[0, 1] = tmp;
                    break;
                case 4:
                    if (s[0, 0] == s[1, 0] && s[0, 0] == s[2, 0]) return false;
                    tmp = s[2, 0];
                    s[2, 0] = s[1, 0];
                    s[1, 0] = s[0, 0];
                    s[0, 0] = tmp;
                    break;
                case 3:
                    if (s[2, 2] == s[2, 1] && s[2, 2] == s[2, 0]) return false;
                    tmp = s[2, 0];
                    s[2, 0] = s[2, 1];
                    s[2, 1] = s[2, 2];
                    s[2, 2] = tmp;
                    break;
                case 2:
                    if (s[1, 2] == s[1, 1] && s[1, 2] == s[1, 0]) return false;
                    tmp = s[1, 0];
                    s[1, 0] = s[1, 1];
                    s[1, 1] = s[1, 2];
                    s[1, 2] = tmp;
                    break;
                case 1:
                    if (s[0, 2] == s[0, 1] && s[0, 2] == s[0, 0]) return false;
                    tmp = s[0, 0];
                    s[0, 0] = s[0, 1];
                    s[0, 1] = s[0, 2];
                    s[0, 2] = tmp;
                    break;
            }
            return true;
        }
        private int getSilverFlopArrayCombo(char[,] s, out string result_string)
        {
            int combo = 0;
            if (s[0, 0] == s[0, 1] && s[0, 0] == s[0, 2]) combo++;
            if (s[1, 0] == s[1, 1] && s[1, 0] == s[1, 2]) combo++;
            if (s[2, 0] == s[2, 1] && s[2, 0] == s[2, 2]) combo++;

            if (s[0, 0] == s[1, 0] && s[0, 0] == s[2, 0]) combo++;
            if (s[0, 1] == s[1, 1] && s[0, 1] == s[2, 1]) combo++;
            if (s[0, 2] == s[1, 2] && s[0, 2] == s[2, 2]) combo++;

            if (s[0, 0] == s[1, 1] && s[0, 0] == s[2, 2]) combo++;
            if (s[2, 0] == s[1, 1] && s[2, 0] == s[0, 2]) combo++;
            result_string = "";
            for (int i = 0, j = 0; i < 3; i++)
                for (j = 0; j < 3; j++)
                    result_string += s[i, j];
            return combo;
        }
        /// <summary>
        /// 0=success, 1=http error, 2=no remain number, 3=, 10=other
        /// </summary>
        /// <returns></returns>
        public int handleSilverFlopInfo(ProtocolMgr protocol, ILogger logger)
        {
            string url = "/root/giftEvent!getCopperEventGiftInfo.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "获取银币翻牌信息");
            if (result == null) return 1;
            if (!result.CmdSucceed) return 10;
            XmlDocument xml = result.CmdResult;
            int _squareNow = 0, _remainNum = 0, _baseSilver = 0, _remainDoubleNum = 0;
            handleSilverFlopNode(protocol, logger, xml, ref _squareNow, ref _remainNum, ref _baseSilver, ref _remainDoubleNum);

            // start flop info
            if (_remainNum == 0) return 2;
            int count = 20;
            while (_remainNum > 0 && count > 0)
            {
                count--;
                bool use_double = _remainDoubleNum > 0;
                string squares = Convert.ToString(_squareNow, 2);
                if (squares.Length < 9)
                {
                    for (int i = 0, len = 9 - squares.Length; i < len; i++) squares = "0" + squares;
                }

                string square_max = "", square_tmp; int combo_max = 0, combo_tmp = 0, step_1_tmp = 0, step_2_tmp = 0;
                int step_1_max = 0, step_2_max = 0;
                for (int i = 0, j = 0, k = 0, m = 0; i < 13; i++)
                {
                    char[,] arr_square = new char[3, 3];
                    for (k = 0; k < 3; k++)
                    {
                        arr_square[k, 0] = squares[k * 3];
                        arr_square[k, 1] = squares[k * 3 + 1];
                        arr_square[k, 2] = squares[k * 3 + 2];
                    }
                    // do step 1
                    if (doSilverFlopStep(arr_square, i)) step_1_tmp = i;
                    else step_1_tmp = 0;
                    combo_tmp = getSilverFlopArrayCombo(arr_square, out square_tmp);
                    if (combo_tmp == 8)
                    {
                        getSilverFlopReward(protocol, logger, i, 0, square_tmp, combo_tmp, use_double, ref _squareNow, ref _remainNum, ref _baseSilver, ref _remainDoubleNum);
                        if (_remainNum == 0) return 2;
                    }
                    else if (combo_tmp > combo_max)
                    {
                        square_max = square_tmp;
                        combo_max = combo_tmp;
                        step_1_max = step_1_tmp;
                        step_2_max = 0;
                    }
                    if (step_1_tmp == 0) continue; // 必须第一次动了才能动第二次, 所以如果i=0, 那么j不可能>0
                    for (j = 0; j < 13; j++)
                    {
                        char[,] arr_square_2 = new char[3, 3];
                        for (k = 0; k < 3; k++)
                            for (m = 0; m < 3; m++)
                                arr_square_2[k, m] = arr_square[k, m];
                        // do step 2
                        if (doSilverFlopStep(arr_square_2, j)) step_2_tmp = j;
                        else step_2_tmp = 0;
                        combo_tmp = getSilverFlopArrayCombo(arr_square_2, out square_tmp);
                        if (combo_tmp == 8)
                        {
                            getSilverFlopReward(protocol, logger, i, j, square_tmp, combo_tmp, use_double, ref _squareNow, ref _remainNum, ref _baseSilver, ref _remainDoubleNum);
                            if (_remainNum == 0) return 2;
                        }
                        else if (combo_tmp > combo_max)
                        {
                            square_max = square_tmp;
                            combo_max = combo_tmp;
                            step_1_max = step_1_tmp;
                            step_2_max = step_2_tmp;
                        }
                    }
                }
                getSilverFlopReward(protocol, logger, step_1_max, step_2_max, square_max, combo_max, use_double, ref _squareNow, ref _remainNum, ref _baseSilver, ref _remainDoubleNum);
            }
            
            return 0;
        }
        private void getSilverFlopReward(ProtocolMgr protocol, ILogger logger, int step1, int step2, string final_result, int combo, bool use_double,
            ref int _squareNow, ref int _remainNum, ref int _baseSilver, ref int _remainDoubleNum)
        {
            string url = "/root/giftEvent!getCopperEventReward.action";
            string data = String.Format("step2={0}&square={1}&combo={2}&step1={3}", step2, final_result, combo, step1);
            if (use_double) data += "&doubleCard=1";
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "获取银币翻牌奖励");
            if (result == null) return;
            if (!result.CmdSucceed) return;
            if (use_double)
                logInfo(logger, String.Format("双倍银币翻牌,最终模型为[{0}],Combo为[{1}],翻动分别为[{2}, {3}], 获得银币[{4}]",
                    final_result, combo, step1, step2, 2 * _baseSilver * (combo + 1)));
            else
                logInfo(logger, String.Format("单倍银币翻牌,最终模型为[{0}],Combo为[{1}],翻动分别为[{2}, {3}], 获得银币[{4}]",
                    final_result, combo, step1, step2, _baseSilver * (combo + 1)));
            XmlDocument xml = result.CmdResult;
            handleSilverFlopNode(protocol, logger, xml, ref _squareNow, ref _remainNum, ref _baseSilver, ref _remainDoubleNum);
        }
        private void handleSilverFlopNode(ProtocolMgr protocol, ILogger logger, XmlDocument xml,
            ref int _squareNow, ref int _remainNum, ref int _baseSilver, ref int _remainDoubleNum)
        {
            // 碗为0, 钱为1
            XmlNode square_node = xml.SelectSingleNode("/results/square");
            if (square_node != null) Int32.TryParse(square_node.InnerText, out _squareNow);
            else _squareNow = 0;

            XmlNode remainNum_node = xml.SelectSingleNode("/results/remainnum");
            if (remainNum_node != null) Int32.TryParse(remainNum_node.InnerText, out _remainNum);
            else _remainNum = 0;

            XmlNode basecopper_node = xml.SelectSingleNode("/results/basecopper");
            if (basecopper_node != null) Int32.TryParse(basecopper_node.InnerText, out _baseSilver);
            else _baseSilver = 0;

            XmlNode double_node = xml.SelectSingleNode("/results/freedouble");
            if (double_node != null) Int32.TryParse(double_node.InnerText, out _remainDoubleNum);
            else _remainDoubleNum = 0;

            logInfo(logger, String.Format("银币翻牌还剩[{0}]次, 剩余翻倍[{1}]次", _remainNum, _remainDoubleNum));
        }
        #endregion

        #region gem flop
        private int[] _gemFlopLevelRewards = new int[] { 2, 4, 6, 9, 12 };
        private int _gemFlopMaxGemLevel = 5;
        private int _gemFlopUpgradeGold = 8;
        private string getGemPatternLevelString(int level_0, int level_1, int level_2)
        {
            return String.Format("{0},{1},{2}", level_0, level_1, level_2);
        }
        private string getGemPatternString(int level_0, int level_1, int level_2)
        {
            string pattern = "";
            string[] pstrs = new string[] { "蓝", "绿", "黄", "红", "紫" };
            if (level_0 > 0 && level_0 <= pstrs.Length) pattern += pstrs[level_0 - 1];
            if (level_0 > 1 && level_1 <= pstrs.Length) pattern += pstrs[level_1 - 1];
            if (level_0 > 2 && level_2 <= pstrs.Length) pattern += pstrs[level_2 - 1];
            return pattern;
        }
        private string getGemPatternString(string orig_pattern)
        {
            string[] gemlevelstrs = orig_pattern.Split(',');
            List<int> gemlevels = new List<int>();
            foreach (string gemlevelstr in gemlevelstrs)
            {
                if (gemlevelstr == null || gemlevelstr.Length == 0) continue;
                int tmp = 0;
                Int32.TryParse(gemlevelstr, out tmp);
                if (tmp > 0) gemlevels.Add(tmp);
            }
            if (gemlevels.Count < 3) return "";
            return getGemPatternString(gemlevels[0], gemlevels[1], gemlevels[2]);
        }
        public string findGemPattern(int max_upgrade, double gem_price, int gold_available, int _upgradeGold, string orig_pattern, bool use_double, 
            out int final_usegold, out int final_gemcount)
        {
            string final_pattern = "";
            final_usegold = 0; final_gemcount = 0;
            string[] gemlevelstrs = orig_pattern.Split(',');
            List<int> gemlevels = new List<int>();
            foreach (string gemlevelstr in gemlevelstrs)
            {
                if (gemlevelstr == null || gemlevelstr.Length == 0) continue;
                int tmp = 0;
                Int32.TryParse(gemlevelstr, out tmp);
                if (tmp > 0) gemlevels.Add(tmp);
            }
            if (gemlevels.Count < 3) return "";
            int level_0 = gemlevels[0], level_1 = gemlevels[1], level_2 = gemlevels[2];
            int has_combo = 0;
            int usegoldTmp = 0, gemCountTmp = 0, extraGemTmp = 0, orig_gemcount = getPatternGems(level_0, level_1, level_2, use_double, out has_combo);
            // initial 
            final_usegold = 0; final_gemcount = orig_gemcount; final_pattern = orig_pattern;
            // 如果金币已经超额了, 那么直接返回最开始数据
            if (gold_available < _upgradeGold)
            {
                return final_pattern;
            }

            // 只允许升级_maxUpgrade次
            int i, j, k, upgrade_now = 0;
            int len_i = _gemFlopMaxGemLevel - gemlevels[0], len_j = _gemFlopMaxGemLevel - gemlevels[1], len_k = _gemFlopMaxGemLevel - gemlevels[2];
            for (i = 0; i <= len_i; i++) // 第一个升级
            {
                //第一个升级i次, 即level+i
                upgrade_now = i;
                if (upgrade_now > max_upgrade) break;
                usegoldTmp = upgrade_now * _upgradeGold;
                if (gold_available < usegoldTmp) break;

                gemCountTmp = getPatternGems(level_0 + i, level_1, level_2, use_double, out has_combo);
                extraGemTmp = gemCountTmp - orig_gemcount;
                //如果宝石价格小于等于全局定义价格, 那么计算, 否则忽略
                if (extraGemTmp > 0 && (1.0 * usegoldTmp / extraGemTmp) <= gem_price)
                {
                    if (final_gemcount < gemCountTmp)
                    {
                        final_usegold = usegoldTmp; final_gemcount = gemCountTmp;
                        final_pattern = getGemPatternLevelString(level_0 + i, level_1, level_2);
                    }
                }

                for (j = 0; j <= len_j; j++) // 第二个升级
                {
                    // 第二个升级j次, 即level+j
                    upgrade_now = i + j;
                    if (upgrade_now > max_upgrade) break;
                    usegoldTmp = upgrade_now * _upgradeGold;
                    if (gold_available < usegoldTmp) break;

                    gemCountTmp = getPatternGems(level_0 + i, level_1 + j, level_2, use_double, out has_combo);
                    extraGemTmp = gemCountTmp - orig_gemcount;
                    //如果宝石价格小于等于全局定义价格, 那么计算, 否则忽略
                    if (extraGemTmp > 0 && (1.0 * usegoldTmp / extraGemTmp) <= gem_price)
                    {
                        if (final_gemcount < gemCountTmp)
                        {
                            final_usegold = usegoldTmp; final_gemcount = gemCountTmp;
                            final_pattern = getGemPatternLevelString(level_0 + i, level_1 + j, level_2);
                        }
                    }

                    for (k = 0; k <= len_k; k++) // 第三个升级
                    {
                        //第三个升级k次, 即level+k
                        // 第二个升级j次, 即level+j
                        upgrade_now = i + j + k;
                        if (upgrade_now > max_upgrade) break;
                        usegoldTmp = upgrade_now * _upgradeGold;
                        if (gold_available < usegoldTmp) break;

                        gemCountTmp = getPatternGems(level_0 + i, level_1 + j, level_2 + k, use_double, out has_combo);
                        extraGemTmp = gemCountTmp - orig_gemcount;
                        //如果宝石价格小于等于全局定义价格, 那么计算, 否则忽略
                        if (extraGemTmp > 0 && (1.0 * usegoldTmp / extraGemTmp) <= gem_price)
                        {
                            if (final_gemcount < gemCountTmp)
                            {
                                final_usegold = usegoldTmp; final_gemcount = gemCountTmp;
                                final_pattern = getGemPatternLevelString(level_0 + i, level_1 + j, level_2 + k);
                            }
                        }
                    }
                }
            }
            return final_pattern;
        }
        private int getPatternGems(int level_0, int level_1, int level_2, bool useDouble, out int hasCombo)
        {
            hasCombo = 0;
            int gemcount = 0;
            if (_gemFlopLevelRewards.Length > level_0) gemcount += _gemFlopLevelRewards[level_0 - 1];
            if (_gemFlopLevelRewards.Length > level_1) gemcount += _gemFlopLevelRewards[level_1 - 1];
            if (_gemFlopLevelRewards.Length > level_2) gemcount += _gemFlopLevelRewards[level_2 - 1];
            if (useDouble) gemcount = gemcount * 2;
            // if same combo
            bool all_same = level_0 == level_1 && level_0 == level_2;
            if (all_same)
            {
                hasCombo = 1;
                return gemcount * 2;
            }
            // if sequence combo
            bool all_sequence = false;
            int level_01 = Math.Abs(level_0 - level_1), level_02 = Math.Abs(level_0 - level_2), level_12 = Math.Abs(level_1 - level_2);
            if (level_01 == 1 && level_02 == 1 && level_12 == 2) all_sequence = true;
            else if (level_01 == 1 && level_02 == 2 && level_12 == 1) all_sequence = true;
            else if (level_01 == 2 && level_02 == 1 && level_12 == 1) all_sequence = true;
            if (all_sequence)
            {
                hasCombo = 2;
                return gemcount * 2;
            }
            return gemcount;
        }
        /// <summary>
        /// 0=success, 1=http error, 2=no remain number, 3=, 10=other
        /// </summary>
        /// <returns></returns>
        public int handleGemFlopInfo(ProtocolMgr protocol, ILogger logger, double gem_price, int gold_available, int max_upgrade)
        {
            string url = "/root/gemCard!getGemCardInfo.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "获取宝石翻牌信息");
            if (result == null) return 1;
            if (!result.CmdSucceed) return 10;
            XmlDocument xml = result.CmdResult;

            string _origPattern = "";
            int _remainNum = 0, _freeDoubleNum = 0;
            handleGemFlopNode(protocol, logger, xml, ref _origPattern, ref _remainNum, ref _freeDoubleNum);

            if (_remainNum == 0) return 2;
            while (_remainNum > 0)
            {
                bool use_double = _freeDoubleNum > 0;
                int final_usegold = 0, final_gemcount = 0;
                string final_pattern = findGemPattern(max_upgrade, gem_price, gold_available, _gemFlopUpgradeGold, _origPattern, use_double, 
                    out final_usegold, out final_gemcount);
                getGemFlopReward(protocol, logger, final_usegold, use_double, _origPattern, final_pattern, final_gemcount,
                     ref _origPattern, ref _remainNum, ref _freeDoubleNum);
            }

            return 0;
        }
        public void getGemFlopReward(ProtocolMgr protocol, ILogger logger, int costGold, bool useDouble, 
            string origin_pattern, string final_pattern, int gemcount,
             ref string _origPattern, ref int _remainNum, ref int _freeDoubleNum)
        {
            string url = "/root/gemCard!receiveGem.action";
            //cost=16&doubleCard=1&list=2,4,3
            string data = String.Format("cost={0}&doubleCard={1}&list={2}", costGold, useDouble ? 1 : 0, final_pattern);
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "获取宝石翻牌奖励");
            if (result == null) return;
            if (!result.CmdSucceed) return;
            // 只要有combo, 肯定翻倍
            logInfo(logger, String.Format("宝石翻牌,初始模型为[{0}], 最终模型为[{1}],花费[{2}]金币, 获得宝石[{3}]",
                getGemPatternString(origin_pattern), getGemPatternString(final_pattern), costGold, gemcount));
            handleGemFlopNode(protocol, logger, result.CmdResult, ref _origPattern, ref _remainNum, ref _freeDoubleNum);
        }
        private void handleGemFlopNode(ProtocolMgr protocol, ILogger logger, XmlDocument xml, ref string _origPattern, ref int _remainNum, ref int _freeDoubleNum)
        {
            // reward gem count
            XmlNodeList reward_nodes = xml.SelectNodes("/results/reward");
            foreach (XmlNode reward_node in reward_nodes)
            {
                if (reward_node == null || !reward_node.HasChildNodes) continue;
                XmlNodeList childs = reward_node.ChildNodes;
                int level = 0, gemcount = 0;
                foreach (XmlNode child in childs)
                {
                    if (child.Name == "baoshilevel") Int32.TryParse(child.InnerText, out level);
                    else if (child.Name == "rewardbaoshinum") Int32.TryParse(child.InnerText, out gemcount);
                }
                if (level > 0 && level < _gemFlopLevelRewards.Length)
                {
                    _gemFlopLevelRewards[level - 1] = gemcount;
                }
            }
            // 
            XmlNode upgradeGold_node = xml.SelectSingleNode("/results/gemcardinfo/upgradegold");
            if (upgradeGold_node != null) Int32.TryParse(upgradeGold_node.InnerText, out _gemFlopUpgradeGold);
            else _gemFlopUpgradeGold = 0;
            XmlNode remainNum_node = xml.SelectSingleNode("/results/gemcardinfo/freetimes");
            if (remainNum_node != null) Int32.TryParse(remainNum_node.InnerText, out _remainNum);
            else _remainNum = 0;
            XmlNode free_double_node = xml.SelectSingleNode("/results/gemcardinfo/freedouble");
            if (free_double_node != null) Int32.TryParse(free_double_node.InnerText, out _freeDoubleNum);
            else _freeDoubleNum = 0;

            XmlNode orig_pattern_node = xml.SelectSingleNode("/results/gemcardinfo/gemcardliststring");
            if (orig_pattern_node != null) _origPattern = orig_pattern_node.InnerText;

            logInfo(logger, String.Format("宝石翻牌还剩[{0}]次, 双倍次数还剩{1}次", _remainNum, _freeDoubleNum));
        }
        #endregion

        #region crossplatform compete
        /// <summary>
        /// 0=success, 1=httpfailure, 2=not start, 3=finished, 4=not at compete time
        /// </summary>
        /// <returns></returns>
        public int handleCrossPlatformCompeteInfo(ProtocolMgr protocol, ILogger logger,
            int gold_available, int max_gold_to_continue_support, out long cdMSeconds)
        {
            int _cdMiliSeconds = 0, _supportId = 0, _supportTimes = 0;
            int _attackerId = 0, _attackerLevel = 0, _attackerRevenge = 0; string _attackerName = "";
            int _defenderId = 0, _defenderLevel = 0, _defenderRevenge = 0; string _defenderName = "";
            bool can_continue_support = false; int support_gold = 0;

            #region get info
            string url = "/root/kfzb!getMatchDetail.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "获取跨服争霸赛信息");
            if (result == null) { cdMSeconds = 30*1000; return 1; }
            if (!result.CmdSucceed) { cdMSeconds = an_hour_later(); return 4; }
            XmlDocument xml = result.CmdResult;

            XmlNode winner_node = xml.SelectSingleNode("/results/message/winnerinfo");
            if (winner_node != null) { cdMSeconds = next_day(); return 3; }

            XmlNode attacker_node = xml.SelectSingleNode("/results/message/attacker");
            if (attacker_node == null)
            {
                XmlNode starttime_node = xml.SelectSingleNode("/results/message/battletime1");
                if (starttime_node != null)
                {
                    DateTime dt = DateTime.Parse(starttime_node.InnerText);
                    DateTime dtnow = DateTime.Now;
                    TimeSpan span = dt - dtnow;
                    if (span.TotalMilliseconds > 0) _cdMiliSeconds = (int)span.TotalMilliseconds;
                }
                cdMSeconds = _cdMiliSeconds - 30 * 1000;
                return 2;
            }

            XmlNode results = xml.SelectSingleNode("/results/message");
            XmlNodeList childs = results.ChildNodes;
            foreach (XmlNode child in childs)
            {
                if (child.Name == "supportcompetitorid") _supportId = Int32.Parse(child.InnerText);
                else if (child.Name == "supporttimes") _supportTimes = Int32.Parse(child.InnerText);
                else if (child.Name == "cd") _cdMiliSeconds = Int32.Parse(child.InnerText);
                else if (child.Name == "attacker")
                {
                    XmlNodeList attackers = child.ChildNodes;
                    foreach (XmlNode anode in attackers)
                    {
                        if (anode.Name == "playerlevel") _attackerLevel = Int32.Parse(anode.InnerText);
                        else if (anode.Name == "competitorid") _attackerId = Int32.Parse(anode.InnerText);
                        else if (anode.Name == "playername") _attackerName = anode.InnerText;
                        else if (anode.Name == "revenge") _attackerRevenge = Int32.Parse(anode.InnerText);
                    }
                }
                else if (child.Name == "defender")
                {
                    XmlNodeList attackers = child.ChildNodes;
                    foreach (XmlNode anode in attackers)
                    {
                        if (anode.Name == "playerlevel") _defenderLevel = Int32.Parse(anode.InnerText);
                        else if (anode.Name == "competitorid") _defenderId = Int32.Parse(anode.InnerText);
                        else if (anode.Name == "playername") _defenderName = anode.InnerText;
                        else if (anode.Name == "revenge") _defenderRevenge = Int32.Parse(anode.InnerText);
                    }
                }
            }
            XmlNode can_buy_gold_node = xml.SelectSingleNode("/results/message/canbuymorereward");
            if (can_buy_gold_node != null) can_continue_support = can_buy_gold_node.InnerText == "1";
            XmlNode buy_gold_node = xml.SelectSingleNode("/results/message/buymorerewardgold");
            if (buy_gold_node != null) Int32.TryParse(buy_gold_node.InnerText, out support_gold);
            #endregion

            if (_cdMiliSeconds > 1000 * 300) { cdMSeconds = _cdMiliSeconds - 300 * 1000; return 0; }
            cdMSeconds = _cdMiliSeconds;
            if (_supportId > 0)
            {
                if (support_gold > max_gold_to_continue_support || gold_available < support_gold)
                {
                    cdMSeconds = immediate();
                    return 0;
                }
            }
            if (_attackerId == 0 || _defenderId == 0) { cdMSeconds = 250 * 1000; return 0; }
            // check which to support
            int attackPoints = 2, defenderPoints = 0; // 攻防基础分值2分
            if (_attackerLevel > _defenderLevel) attackPoints += 6; // 级别高算6分
            else if (_attackerLevel < _defenderLevel) defenderPoints += 6;
            attackPoints += _attackerRevenge; // 每次复仇算1分
            defenderPoints += _defenderRevenge;

            int counter = 0;
            while (can_continue_support && gold_available >= support_gold && support_gold <= max_gold_to_continue_support && counter < 3)
            {
                gold_available -= support_gold;
                if (attackPoints >= defenderPoints)
                    supportCompete(protocol, logger, _attackerId, _attackerLevel, 
                        true, _attackerName, _defenderName, out can_continue_support, out support_gold);
                else 
                    supportCompete(protocol, logger, _defenderId, _defenderLevel,
                        false, _attackerName, _defenderName, out can_continue_support, out support_gold);
                counter++;
            }

            return 0;
        }
        private bool supportCompete(ProtocolMgr protocol, ILogger logger, int competorId, int level, 
            bool isattacker, string _attackerName, string _defenderName, out bool can_continue_support, out int support_gold)
        {
            can_continue_support = false;
            support_gold = 1000;
            string url = "/root/kfzb!support.action";
            string data = "competitorId=" + competorId;
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "支持争霸赛");
            if (result == null || !result.CmdSucceed) return false;
            XmlDocument xml = result.CmdResult;
            //<results>
            //    <state>1</state>
            //    <message>
            //        <canbuymorereward>1</canbuymorereward>
            //        <buymorerewardgold>5</buymorerewardgold>
            //        <supportcompetitorid>750947</supportcompetitorid>
            //        <supporttimes>1</supporttimes>
            //        <supporttickets>1000</supporttickets>
            //        <supportxs>1</supportxs>
            //        <banquet>
            //            <dayorder>1</dayorder>
            //            <day1num>4</day1num>
            //            <day2num>0</day2num>
            //            <day3num>0</day3num>
            //        </banquet>
            //    </message>
            //</results>            
            XmlNode can_buy_gold_node = xml.SelectSingleNode("/results/message/canbuymorereward");
            if (can_buy_gold_node != null) can_continue_support = can_buy_gold_node.InnerText == "1";
            XmlNode buy_gold_node = xml.SelectSingleNode("/results/message/buymorerewardgold");
            if (buy_gold_node != null) Int32.TryParse(buy_gold_node.InnerText, out support_gold);

            // xml 简单, 忽略
            string desc = String.Format("支持争霸赛, 用户[{0}:{1}级]", isattacker ? _attackerName : _defenderName, level);
            logInfo(logger, desc);
            return true;
        }
        #endregion

        #region jail event
        /// <summary>
        /// 0=success, 1=http error, 10=cmd error
        /// </summary>
        /// <returns></returns>
        public int handleJailEventInfo(ProtocolMgr protocol, ILogger logger, User user)
        {
            string url = "/root/jail!getJailEventInfo.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "获取典狱活动信息");
            if (result == null) return 1;
            if (!result.CmdSucceed) { user.removeActivity(ActivityType.JailEvent); return 10; }
            user.addActivity(ActivityType.JailEvent);
            XmlDocument xml = result.CmdResult;
            List<Slave> _slaves = new List<Slave>();
            
            XmlNodeList onenpc_nodes = xml.SelectNodes("/results/onenpc");
            foreach (XmlNode onenpc_node in onenpc_nodes)
            {
                if (onenpc_node == null || !onenpc_node.HasChildNodes) continue;
                XmlNode state_node = onenpc_node.SelectSingleNode("state");
                int state = -1; //-1=未开启, 0=可以抓捕(抓了没宝石), 1=已抓捕, 2=已劳动, 3=可以抓捕而且有宝石加成(抓了就有宝石)
                if (state_node != null) Int32.TryParse(state_node.InnerText, out state);
                if (state == -1 || state == 2) continue;
                Slave s = new Slave();
                s.state = state;
                XmlNode id_node = onenpc_node.SelectSingleNode("jailevent/id");
                if (id_node != null) s.id = Int32.Parse(id_node.InnerText);
                XmlNode name_node = onenpc_node.SelectSingleNode("jailevent/name");
                if (name_node != null) s.name = name_node.InnerText;
                XmlNode gem_node = onenpc_node.SelectSingleNode("jailevent/baoshi");
                if (gem_node != null) s.baoshi = Int32.Parse(gem_node.InnerText);
                _slaves.Add(s);
            }
            
            if (_slaves.Count == 0) return 0;
            foreach (Slave s in _slaves)
            {
                if (s.state == 0 || s.state == 3)
                {
                    catchSlave(protocol, logger, s);
                    slashSlave(protocol, logger, s);
                }
                else if (s.state == 1) slashSlave(protocol, logger, s);
            }
            return 0;
        }
        private int catchSlave(ProtocolMgr protocol, ILogger logger, Slave s)
        {
            string url = "/root/jail!catchJailEvent.action";
            string data = "slaveId=" + s.id;
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "抓捕典狱活动NPC");
            if (result == null) return 1;
            if (!result.CmdSucceed) return 2;
            XmlDocument xml = result.CmdResult;
            //<results><state>1</state><catchreward><baoshi>0</baoshi></catchreward></results>
            int reward_gemcount = 0;
            XmlNode reward_gemcount_node = xml.SelectSingleNode("/results/catchreward/baoshi");
            if (reward_gemcount_node != null) Int32.TryParse(reward_gemcount_node.InnerText, out reward_gemcount);
            logInfo(logger, String.Format("抓捕典狱活动NPC [{0}] 成功, 获得宝石+{1}", s.name, reward_gemcount));
            return 0;
        }
        private int slashSlave(ProtocolMgr protocol, ILogger logger, Slave s)
        {
            string url = "/root/jail!slash.action";
            string data = "slaveId=Event:" + s.id;
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "劳动典狱活动NPC");
            if (result == null) return 1;
            if (!result.CmdSucceed) return 2;
            XmlDocument xml = result.CmdResult;
            //<results><state>1</state><baoshi>22</baoshi><buff>2</buff></results>
            int baoshi = 0;
            XmlNode baoshi_node = xml.SelectSingleNode("/results/baoshi");
            if (baoshi_node != null) Int32.TryParse(baoshi_node.InnerText, out baoshi);
            logInfo(logger, String.Format("劳动典狱活动NPC [{0}] 成功, 获得宝石+{1}", s.name, baoshi));
            return 0;
        }
        private class Slave
        {
            //<id>3</id>
            //<name>董卓</name>
            //<pic>dongzhuo</pic>
            //<baoshi>200</baoshi>
            //<buff>2</buff>
            public int id;
            public string name;
            public int baoshi;
            /// <summary>
            /// -1=未开启, 0=可以抓捕(抓了没宝石), 1=已抓捕, 2=已劳动, 3=可以抓捕而且有宝石加成(抓了就有宝石)
            /// </summary>
            public int state;
        }
        #endregion

        #region player compete
        /// <summary>
        /// 0=success, 1=http error, 10=cmd error
        /// </summary>
        /// <returns></returns>
        public int handlePlayerCompeteSignupInfo(ProtocolMgr protocol, ILogger logger, bool buy_reward, int gold_available)
        {
            int _signup_state = 0, _current_group = 0, _cd = 0;
            string url = "/root/kfwd!getSignupList.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "获取武斗会报名信息");
            if (result == null) return 1;
            if (!result.CmdSucceed) return 10;
            XmlDocument xml = result.CmdResult;
            XmlNode signup_state_node = xml.SelectSingleNode("/results/message/signupstate");
            if (signup_state_node != null) Int32.TryParse(signup_state_node.InnerText, out _signup_state);

            XmlNode currentgroup_node = xml.SelectSingleNode("/results/message/currentgroup");
            if (currentgroup_node != null) Int32.TryParse(currentgroup_node.InnerText, out _current_group);

            XmlNode cd_node = xml.SelectSingleNode("/results/message/cd");
            if (cd_node != null) Int32.TryParse(cd_node.InnerText, out _cd);

            if (_current_group > 0)
            {
                if (_signup_state == 0) signupMe(protocol, logger);
            }

            if (_cd < 0) // completed
            {
                int get_result = getTributeDetail(protocol, logger, buy_reward, gold_available);
            }

            return 0;
        }
        public int getTributeDetail(ProtocolMgr protocol, ILogger logger, bool buy_reward, int gold_available)
        {
            string url = "/root/kfwd!getTributeDetail.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "获取武斗会奖励信息");
            if (result == null) return 1;
            if (!result.CmdSucceed) return 2;
            XmlDocument xml = result.CmdResult;

            bool has_score_reward = false;
            XmlNode score_reward_node = xml.SelectSingleNode("/results/message/scoreticketsreward");
            if (score_reward_node != null) has_score_reward = score_reward_node.InnerText == "1";
            if (has_score_reward) getScoreTicketReward(protocol, logger);

            XmlNodeList reward_nodes = xml.SelectNodes("/results/message/tributeinfo/tributelist/tribute");
            foreach (XmlNode reward_node in reward_nodes)
            {
                if (reward_node == null || !reward_node.HasChildNodes) continue;
                int gold = 0, ticket = 0, state = 2; // 2=未开启, 1=已开启

                XmlNode ticket_node = reward_node.SelectSingleNode("tickets");
                if (ticket_node != null) Int32.TryParse(ticket_node.InnerText, out ticket);
                else ticket = 0;

                XmlNode gold_node = reward_node.SelectSingleNode("gold");
                if (gold_node != null) Int32.TryParse(gold_node.InnerText, out gold);
                else gold = 0;

                XmlNode state_node = reward_node.SelectSingleNode("state");
                if (state_node != null) Int32.TryParse(state_node.InnerText, out state);
                else state = 2;

                if (state == 1) continue;
                if (state == 2)
                {
                    if (gold == 0) buyTributeReward(protocol, logger, 0, ticket);
                    else if (buy_reward && gold_available > gold)
                    {
                        buyTributeReward(protocol, logger, gold, ticket);
                        gold_available -= gold;
                    }
                }
            }
            return 0;
        }
        public int getScoreTicketReward(ProtocolMgr protocol, ILogger logger)
        {
            string url = "/root/kfwd!getScoreTicketsReward.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "购买武斗会积分奖励");
            if (result == null) return 1;
            if (!result.CmdSucceed) return 2;
            XmlDocument xml = result.CmdResult;
            //<results><state>1</state><message><tickets>10500</tickets><mytickets>92511</mytickets></message></results>
            int ticket = 0;
            XmlNode ticket_node = xml.SelectSingleNode("/results/message/tickets");
            if (ticket_node != null) Int32.TryParse(ticket_node.InnerText, out ticket);
            else ticket = 0;
            logInfo(logger, String.Format("获取武斗会积分奖励, 点券+{0}", ticket));
            return 0;
        }
        public int buyTributeReward(ProtocolMgr protocol, ILogger logger, int gold, int ticket)
        {
            string url = "/root/kfwd!buyTribute.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "购买武斗会点券宝箱");
            if (result == null) return 1;
            if (!result.CmdSucceed) return 2;
            logInfo(logger, String.Format("购买武斗会点券宝箱, 使用金币[{0}], 点券+{1}, ", gold, ticket));
            return 0;
        }
        public int signupMe(ProtocolMgr protocol, ILogger logger)
        {
            string url = "/root/kfwd!signUp.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "报名武斗会");
            if (result == null) return 1;
            if (!result.CmdSucceed) return 2;
            XmlDocument xml = result.CmdResult;
            logInfo(logger, "报名武斗会成功");
            return 0;
        }
        public int syncMyData(ProtocolMgr protocol, ILogger logger)
        {
            string url = "/root/kfwd!syncData.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "武斗会同步数据");
            if (result == null) return 1;
            if (!result.CmdSucceed) return 2;
            XmlDocument xml = result.CmdResult;
            logInfo(logger, "武斗会同步数据成功");
            return 0;
        }
        #endregion

        #region player compete event
        /// <summary>
        /// 0=success, 1=http failure, 2= 10=cmd error
        /// </summary>
        /// <param name="protocol"></param>
        /// <param name="logger"></param>
        /// <returns></returns>
        public int handlePlayerCompeteEventInfo(ProtocolMgr protocol, ILogger logger, bool buy_reward, int gold_available)
        {
            string url = "/root/kfEvent!getKfwdEventInfo.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "获取武斗会庆祝活动信息");
            if (result == null) return 1;
            if (!result.CmdSucceed) return 10;
            XmlDocument xml = result.CmdResult;

            int _max_event_reward_times = 0, _got_event_reward_times = 0, _event_reward_gold = 0, _event_need_gold = 0, _event_reward_tickets = 0;
            handleEventInfoNodes(xml, ref _max_event_reward_times, ref _got_event_reward_times, ref _event_reward_gold, ref _event_need_gold, ref _event_reward_tickets);

            while (_max_event_reward_times > _got_event_reward_times)
            {
                if (_event_reward_gold > 0)
                {
                    getEventReward(protocol, logger, ref _max_event_reward_times, ref _got_event_reward_times, ref _event_reward_gold, ref _event_need_gold, ref _event_reward_tickets);
                    gold_available += _event_reward_gold;
                }
                else if (_event_need_gold > 0)
                {
                    if (buy_reward && gold_available >= _event_need_gold)
                    {
                        getEventReward(protocol, logger, ref _max_event_reward_times, ref _got_event_reward_times, ref _event_reward_gold, ref _event_need_gold, ref _event_reward_tickets);
                        gold_available -= _event_need_gold;
                    }
                    else break;
                }
            }
            return 0;
        }
        private void handleEventInfoNodes(XmlDocument xml, ref int _max_event_reward_times, ref int _got_event_reward_times,
            ref int _event_reward_gold, ref int _event_need_gold, ref int _event_reward_tickets)
        {
            XmlNode maxtimes_node = xml.SelectSingleNode("/results/maxtimes");
            if (maxtimes_node != null) Int32.TryParse(maxtimes_node.InnerText, out _max_event_reward_times);
            else _max_event_reward_times = 0;

            XmlNode gettimes_node = xml.SelectSingleNode("/results/getrewardtimes");
            if (gettimes_node != null) Int32.TryParse(gettimes_node.InnerText, out _got_event_reward_times);
            else _got_event_reward_times = _max_event_reward_times;

            XmlNode rewardgold_node = xml.SelectSingleNode("/results/rewardgold");
            if (rewardgold_node != null) Int32.TryParse(rewardgold_node.InnerText, out _event_reward_gold);
            else _event_reward_gold = 0;

            XmlNode needgold_node = xml.SelectSingleNode("/results/gold");
            if (needgold_node != null) Int32.TryParse(needgold_node.InnerText, out _event_need_gold);
            else _event_need_gold = 0;

            XmlNode reward_tickets_node = xml.SelectSingleNode("/results/tickets");
            if (reward_tickets_node != null) Int32.TryParse(reward_tickets_node.InnerText, out _event_reward_tickets);
            else _event_reward_tickets = 0;
        }
        public int getEventReward(ProtocolMgr protocol, ILogger logger, ref int _max_event_reward_times, ref int _got_event_reward_times,
            ref int _event_reward_gold, ref int _event_need_gold, ref int _event_reward_tickets)
        {
            string url = "/root/kfEvent!getKfwdReward.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "获取武斗会庆祝活动奖励");
            if (result == null) return 1;
            if (!result.CmdSucceed) return 2;
            XmlDocument xml = result.CmdResult;

            // 因为领取的是上一次的奖励, 所以必须在解析这一次数据之前输出奖励信息, 否则就被覆盖啦
            string desc = "";
            if (_event_need_gold > 0) desc += String.Format("使用[{0}]金币购买武斗会庆祝活动奖励, 获得点券+{1}", _event_need_gold, _event_reward_tickets);
            else if (_event_reward_gold > 0) desc += String.Format("领取武斗会庆祝活动奖励, 获得金币+{0}, 点券+{1}", _event_reward_gold, _event_reward_tickets);
            logInfo(logger, desc);

            handleEventInfoNodes(xml, ref _max_event_reward_times, ref _got_event_reward_times, ref _event_reward_gold, ref _event_need_gold, ref _event_reward_tickets);
            return 0;
        } 
        #endregion

        #region kfbanquet
        /// <summary>
        /// return, 0=success, 1=http fail, 10=other
        /// </summary>
        /// <returns></returns>
        public int handleKfBanquetInfo(ProtocolMgr protocol, ILogger logger, User user, int buy_ticket_gold, bool joinSelfNation, int gold_available, out long cdMSeconds)
        {
            int _canJoinNumber = 0, _current_buygold = 1000;
            string url = "/root/kfBanquet.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "获取盛宴活动信息");
            if (result == null) { cdMSeconds = 30 * 1000; return 1; }
            if (!result.CmdSucceed) { cdMSeconds = next_day(); return 10; }
            XmlDocument xml = result.CmdResult;

            XmlNode joinnum_node = xml.SelectSingleNode("/results/canjoinnum");
            if (joinnum_node != null) Int32.TryParse(joinnum_node.InnerXml, out _canJoinNumber);

            XmlNode buygold_node = xml.SelectSingleNode("/results/buyjoingold");
            if (buygold_node != null) Int32.TryParse(buygold_node.InnerXml, out _current_buygold);
            else _current_buygold = 1000;

            XmlNodeList roomnode_list = xml.SelectNodes("/results/room");
            List<RankRoom> _rooms = new List<RankRoom>();

            foreach (XmlNode room_node in roomnode_list)
            {
                if (room_node == null || !room_node.HasChildNodes) continue;
                XmlNodeList childs = room_node.ChildNodes;
                RankRoom room = new RankRoom();
                foreach (XmlNode child in childs)
                {
                    if (child.Name == "rank") room.rank = Int32.Parse(child.InnerText);
                    else if (child.Name == "nation") room.nation = Int32.Parse(child.InnerText);
                    else if (child.Name == "playername") room.playername = child.InnerText;
                    else if (child.Name == "serverid") room.serverid = Int32.Parse(child.InnerText);
                    else if (child.Name == "servername") room.servername = child.InnerText;
                    else if (child.Name == "weinum") room.weinum = Int32.Parse(child.InnerText);
                    else if (child.Name == "shunum") room.shunum = Int32.Parse(child.InnerText);
                    else if (child.Name == "wunum") room.wunum = Int32.Parse(child.InnerText);
                }
                _rooms.Add(room);
            }

            if (gold_available >= _current_buygold && _current_buygold <= buy_ticket_gold)
            {
                bool buy_success = buyBanquet(protocol, logger, _current_buygold);
                if (buy_success) _canJoinNumber++;
            }
            if (_canJoinNumber == 0) { cdMSeconds = next_day(); return 0; }
            if (_rooms.Count == 0) { cdMSeconds = an_hour_later(); return 0; }

            // find room
            RankRoom _room = _rooms[0];
            int user_nation = user.NationInt; //1/2/3 = 魏/蜀/吴
            foreach (RankRoom r in _rooms)
            {
                if (joinSelfNation) { if (r.nation == user_nation) { _room = r; break; } }
                else { if (r.nation != user_nation) { _room = r; break; } }
            }

            bool success = joinBanquet(protocol, logger, _room.rank, _room.playername);
            if (success) cdMSeconds = 10 * 1000;
            else cdMSeconds = 10 * 1000;
            return 0;
        }
        public bool joinBanquet(ProtocolMgr protocol, ILogger logger, int roomId, string name)
        {
            string url = "/root/kfBanquet!joinBanquet.action";
            string data = "room=" + roomId;
            string desc = String.Format("参加第{0}名[{1}]的盛宴", roomId, name);
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, desc);
            if (result == null || !result.CmdSucceed) return false;
            //<results><state>1</state><message></message></results>
            logInfo(logger, desc);
            return true;
        }
        public bool buyBanquet(ProtocolMgr protocol, ILogger logger, int _current_buygold)
        {
            string url = "/root/kfBanquet!buyBanquetNum.action";
            string data = "num=1";
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "购买邀请券");
            if (result == null || !result.CmdSucceed) return false;
            XmlDocument xml = result.CmdResult;
            //<results><state>1</state><message></message></results>
            logInfo(logger, String.Format("使用[{0}]金, 购买邀请券*1", _current_buygold));
            return true;
        }
        public void getRoomInfo(ProtocolMgr protocol, ILogger logger)
        {
            string url = "/root/kfBanquet!getRoomInfo.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "获取参加盛宴信息");
            if (result == null || !result.CmdSucceed) return;
            XmlDocument xml = result.CmdResult;
        }
        public void getRoomReward(ProtocolMgr protocol, ILogger logger)
        {
            string url = "/root/kfBanquet!getRewardInfo.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "获取盛宴奖励");
            if (result == null || !result.CmdSucceed) return;
            XmlDocument xml = result.CmdResult;
        }

        private class RankRoom
        {
            //<room>
            //    <rank>1</rank>
            //    <nation>0</nation>
            //    <playername>houzhiyuan</playername>
            //    <serverid>10</serverid>
            //    <servername>360</servername>
            //    <finishnum>25003</finishnum>
            //    <weinum>2690</weinum>
            //    <shunum>18611</shunum>
            //    <wunum>3702</wunum>
            //    <bufnum>0</bufnum>
            //</room>
            public int rank;
            public int nation;
            public string playername;
            public int serverid;
            public string servername;
            public int weinum;
            public int shunum;
            public int wunum;
        }
        #endregion

        #region world army
        /// <summary>
        /// 0=success, 1=http failure, 2=army defeated, 3=cding 10=other error
        /// </summary>
        /// <param name="protocol"></param>
        /// <param name="logger"></param>
        /// <param name="gold_available"></param>
        /// <param name="buy_box1"></param>
        /// <param name="buy_box2"></param>
        /// <param name="refresh_type">0=nothing, 1=精英to首领, 2=普通to首领</param>
        /// <returns></returns>
        public int handleWorldArmyInfo(ProtocolMgr protocol, ILogger logger, ref int gold_available, int open_box_type,
            bool buy_box1, bool buy_box2, int refresh_type, out long cdMSeconds)
        {
            string url = "/root/nian!getNianInfo.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "获取世界军团信息");
            if (result == null) { cdMSeconds = immediate(); return 1; }
            if (!result.CmdSucceed) { cdMSeconds = next_day(); return 10; }
            XmlDocument xml = result.CmdResult;

            int _daojishi=0, _hongbao_count=0;
            bool _recovering =false, _can_attack = false, _defeated=false;
            string _army_info="";  

            handleArmyNode(protocol, logger, xml, ref gold_available, buy_box1, buy_box2, ref _daojishi, ref _recovering, 
                ref _can_attack, ref _hongbao_count, ref _army_info, ref _defeated);

            if (_defeated) { cdMSeconds = next_day(); return 2; }
            if (_daojishi > 0) { cdMSeconds = _daojishi; return 0; }
            if (_recovering)
            {
                cdMSeconds = 120 * 1000; return 0;// 正在进行中但是不能打, 说明正在恢复兵力, 135秒后继续
            }

            int index = 0; int now_army = 1;
            for (int i = 0; i < _army_info.Length; i++)
            {
                int tmp = Int32.Parse(_army_info.Substring(i, 1));
                if (tmp > now_army)
                {
                    index = i; now_army = tmp;
                }
            }
            int refresh_army_gold = 10;
            if (refresh_type == 1) //仅升级首领
            {
                if (now_army == 2)
                {
                    if (gold_available >= refresh_army_gold)
                    {
                        bool refresh_result = refreshArmyByGold(protocol, logger, 2, ref _army_info);
                        if (refresh_result)
                        {
                            gold_available -= refresh_army_gold;
                            now_army = 3;
                        }
                    }
                }
            }
            else if (refresh_type == 2)//升级精英和首领
            {
                if (now_army == 2)
                {
                    if (gold_available >= refresh_army_gold)
                    {
                        bool refresh_result = refreshArmyByGold(protocol, logger, 2, ref _army_info);
                        if (refresh_result)
                        {
                            gold_available -= refresh_army_gold;
                            now_army = 3;
                        }
                    }
                }
                else if (now_army == 1)
                {
                    if (gold_available >= refresh_army_gold)
                    {
                        bool refresh_result = refreshArmyByGold(protocol, logger, 1, ref _army_info);
                        if (refresh_result)
                        {
                            gold_available -= refresh_army_gold;
                            now_army = 2;
                            if (gold_available >= refresh_army_gold)
                            {
                                refresh_result = refreshArmyByGold(protocol, logger, 2, ref _army_info);
                                if (refresh_result)
                                {
                                    gold_available -= refresh_army_gold;
                                    now_army = 3;
                                }
                            }
                        }
                    }
                }
            }

            int attack_result = attackArmy(protocol, logger, index, now_army, ref gold_available, buy_box1, buy_box2, ref _daojishi, ref _recovering,
                ref _can_attack, ref _hongbao_count, ref _army_info, ref _defeated);
            int boxgold = 0;
            if (open_box_type == 1) { open_box_type = 2; boxgold = 2; }
            else if (open_box_type == 2) { open_box_type = 4; boxgold = 10; }
            else if (open_box_type == 3) { open_box_type = 10; boxgold = 80; }
            for (int i = 0; i < _hongbao_count; i++)
            {
                if (gold_available >= boxgold)
                {
                    openBox(protocol, logger, open_box_type);
                    gold_available -= boxgold;
                }
                else openBox(protocol, logger, 0);
            }
            cdMSeconds = 10 * 1000; // 10秒一次
            return 0;
        }
        private void handleArmyNode(ProtocolMgr protocol, ILogger logger, XmlDocument xml, ref int gold_available, bool buy_box1, bool buy_box2,
            ref int _daojishi, ref bool _recovering, ref bool _can_attack, ref int _hongbao_count,
            ref string _army_info, ref bool _defeated)
        {
            XmlNode daojishi_node = xml.SelectSingleNode("/results/daojishi");
            if (daojishi_node != null) Int32.TryParse(daojishi_node.InnerText, out _daojishi);
            else _daojishi = 0;

            int next_army = 0;
            XmlNode next_army_node = xml.SelectSingleNode("/results/nextarmy");
            if (next_army_node != null) Int32.TryParse(next_army_node.InnerText, out next_army);
            else next_army = 0;
            _recovering = next_army > 0;

            XmlNode can_attack_node = xml.SelectSingleNode("/results/canattack");
            if (can_attack_node != null) _can_attack = can_attack_node.InnerText.Equals("true");
            else _can_attack = false;

            XmlNode hongbao_node = xml.SelectSingleNode("/results/hongbao");
            if (hongbao_node != null) Int32.TryParse(hongbao_node.InnerText, out _hongbao_count);
            else _hongbao_count = 0;

            XmlNode army_node = xml.SelectSingleNode("/results/army");
            if (army_node != null) _army_info = army_node.InnerText;
            else _army_info = "";

            XmlNode defeat_node = xml.SelectSingleNode("/results/defeat");
            if (defeat_node != null) _defeated = defeat_node.InnerText.Equals("true");
            else _defeated = false;

            // reward node
            if (buy_box1)
            {

                XmlNode got_node = xml.SelectSingleNode("/results/reward1");
                if (got_node != null && got_node.InnerText.Equals("0"))
                {
                    int gold = 0, ticket = 0;
                    XmlNode gold_node = xml.SelectSingleNode("/results/rewardgold1");
                    if (gold_node != null) Int32.TryParse(gold_node.InnerText, out gold);
                    XmlNode ticket_node = xml.SelectSingleNode("/results/rewardtickets1");
                    if (ticket_node != null) Int32.TryParse(ticket_node.InnerText, out ticket);
                    if (gold_available >= gold)
                    {
                        buyReward(protocol, logger, 1, gold, ticket);
                        gold_available -= gold;
                    }
                }
            }
            if (buy_box2)
            {
                XmlNode got_node = xml.SelectSingleNode("/results/reward2");
                if (got_node != null && got_node.InnerText.Equals("0"))
                {
                    int gold = 0, ticket = 0;
                    XmlNode gold_node = xml.SelectSingleNode("/results/rewardgold2");
                    if (gold_node != null) Int32.TryParse(gold_node.InnerText, out gold);
                    XmlNode ticket_node = xml.SelectSingleNode("/results/rewardtickets2");
                    if (ticket_node != null) Int32.TryParse(ticket_node.InnerText, out ticket);
                    if (gold_available >= gold)
                    {
                        buyReward(protocol, logger, 2, gold, ticket);
                        gold_available -= gold;
                    }
                }
            }
        }
        private int attackArmy(ProtocolMgr protocol, ILogger logger, int armyid, int army_type, ref int gold_available, bool buy_box1, bool buy_box2, 
            ref int _daojishi, ref bool _recovering, ref bool _can_attack, ref int _hongbao_count,
            ref string _army_info, ref bool _defeated)
        {
            string url = "/root/nian!attNian.action";
            string data = "army=" + armyid;
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "攻击世界军团");
            if (result == null) return 1;
            if (!result.CmdSucceed)
            {
                if (result.CmdError.IndexOf("冷却中") >= 0) return 2;
                else return 3;
            }
            XmlDocument xml = result.CmdResult;
            handleArmyNode(protocol, logger, xml, ref gold_available, buy_box1, buy_box2, ref _daojishi, ref _recovering, 
                ref _can_attack, ref _hongbao_count, ref _army_info, ref _defeated);
            int hongbao_add = 0;
            XmlNode ha_node = xml.SelectSingleNode("/results/addhongbao");
            if (ha_node != null) Int32.TryParse(ha_node.InnerText, out hongbao_add);

            string amtype = "";
            if (army_type == 1) amtype = "普通部队";
            else if (army_type == 2) amtype = "精英部队";
            else amtype = "首领部队";
            string desc = String.Format("攻打[{0}]位置[{1}], 获得红包[{2}]个", armyid, amtype, hongbao_add);
            logInfo(logger, desc);
            return 0;
        }
        private bool openBox(ProtocolMgr protocol, ILogger logger, int mode)
        {
            //0=普通开启, 2=双倍开启, 4=4倍, 10=10倍
            string url = "/root/nian!openHonbao.action";
            if (mode != 0 && mode != 2 && mode != 4 && mode != 10) mode = 0;
            string data = "mode=" + mode;
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "打开红包");
            if (result == null || !result.CmdSucceed) return false;
            XmlDocument xml = result.CmdResult;
            int tickets_add = 0;
            XmlNode tk_node = xml.SelectSingleNode("/results/addtickets");
            if (tk_node != null) Int32.TryParse(tk_node.InnerText, out tickets_add);
            string boxstring = "普通模式";
            if (mode == 2) { boxstring = "两倍模式"; }
            else if (mode == 4) { boxstring = "4倍模式"; }
            else if (mode == 10) { boxstring = "10倍模式"; }
            logInfo(logger, String.Format("{0}开启红包, 获得点券[{1}]", boxstring, tickets_add));
            return true;
        }
        private bool buyReward(ProtocolMgr protocol, ILogger logger, int mode, int gold, int ticket)
        {
            string url = "/root/nian!getMoreReward.action";
            string data = "mode=" + mode;
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "购买奖励");
            if (result == null || !result.CmdSucceed) return false;
            XmlDocument xml = result.CmdResult;
            string desc;
            if (mode == 1) desc = String.Format("使用[{0}]金币购买世界军团排名奖励, 点券+{1}", gold, ticket);
            else desc = String.Format("使用[{0}]金币购买世界军团获胜奖励, 点券+{1}", gold, ticket);
            logInfo(logger, desc);
            return true;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="uptype">1=普通部队升级为精英部队,2=精英部队升级为首领部队</param>
        /// <returns></returns>
        public bool refreshArmyByGold(ProtocolMgr protocol, ILogger logger, int uptype, ref string _army_info)
        {
            string url = "/root/nian!refreshNianTroop.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "刷新部队");
            if (result == null || !result.CmdSucceed) return false;
            XmlDocument xml = result.CmdResult;

            //<results><state>1</state><refreshtroop><trooptype>333333</trooptype></refreshtroop></results>
            XmlNode army_node = xml.SelectSingleNode("/results/refreshtroop/trooptype");
            if (army_node != null) _army_info = army_node.InnerText;
            else _army_info = "";

            if (uptype == 1) logInfo(logger, "使用10金币将普通部队升级为精英部队");
            else logInfo(logger, "使用10金币将精英部队升级为首领部队");

            return true;
        }
        #endregion

        #region gift event
        /// <summary>
        /// 0=success, 1=http failure, 10=other error
        /// </summary>
        /// <param name="protocol"></param>
        /// <param name="logger"></param>
        /// <param name="eatSerial"></param>
        /// <returns></returns>
        public int handleGiftEventInfo(ProtocolMgr protocol, ILogger logger, string eatSerial)
        {
            int _rice = 0, _bean = 0, _meat = 0, _egg = 0;
            int _ricebean = 0, _ricemeat = 0, _riceegg = 0;
            bool _beanCanMake = false, _meatCanMake = false, _eggCanMake = false;

            #region get info
            string url = "/root/giftEvent!getDrangonBoatInfo.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "获取玩家犒赏活动信息");
            if (result == null) return 1;
            if (!result.CmdSucceed) return 10;
            XmlDocument xml = result.CmdResult;

            XmlNode rice_node = xml.SelectSingleNode("/results/zongzi/rice");
            if (rice_node != null) Int32.TryParse(rice_node.InnerText, out _rice);

            XmlNode bean_node = xml.SelectSingleNode("/results/zongzi/bean");
            if (bean_node != null) Int32.TryParse(bean_node.InnerText, out _bean);

            XmlNode meat_node = xml.SelectSingleNode("/results/zongzi/meat");
            if (meat_node != null) Int32.TryParse(meat_node.InnerText, out _meat);

            XmlNode egg_node = xml.SelectSingleNode("/results/zongzi/egg");
            if (egg_node != null) Int32.TryParse(egg_node.InnerText, out _egg);

            XmlNode beanCanMake_node = xml.SelectSingleNode("/results/zongzi/ricebean/canmake");
            if (beanCanMake_node != null) _beanCanMake = beanCanMake_node.InnerText == "1";

            XmlNode meatCanMake_node = xml.SelectSingleNode("/results/zongzi/ricemeat/canmake");
            if (meatCanMake_node != null) _meatCanMake = meatCanMake_node.InnerText == "1";

            XmlNode eggCanMake_node = xml.SelectSingleNode("/results/zongzi/riceegg/canmake");
            if (eggCanMake_node != null) _eggCanMake = eggCanMake_node.InnerText == "1";

            XmlNode ricebean_node = xml.SelectSingleNode("/results/zongzi/ricebean/ricebeannum");
            if (ricebean_node != null) Int32.TryParse(ricebean_node.InnerText, out _ricebean);

            XmlNode ricemeat_node = xml.SelectSingleNode("/results/zongzi/ricemeat/ricemeatnum");
            if (ricemeat_node != null) Int32.TryParse(ricemeat_node.InnerText, out _ricemeat);

            XmlNode riceegg_node = xml.SelectSingleNode("/results/zongzi/riceegg/riceeggnum");
            if (riceegg_node != null) Int32.TryParse(riceegg_node.InnerText, out _riceegg);
            #endregion

            string serial = "231";
            if (eatSerial != null && eatSerial.Length > 0) serial = eatSerial;
            List<int> _getGiftSerial = new List<int>();

            for (int i = 0, len = serial.Length; i < len; i++)
            {
                char ch = serial[i];
                if (ch.Equals('1'))
                {
                    if (!_getGiftSerial.Contains(1)) _getGiftSerial.Add(1);
                }
                else if (ch.Equals('2'))
                {
                    if (!_getGiftSerial.Contains(2)) _getGiftSerial.Add(2);
                }
                else if (ch.Equals('3'))
                {
                    if (!_getGiftSerial.Contains(3)) _getGiftSerial.Add(3);
                }
                if (_getGiftSerial.Count >= 3) break;
            }

            // make
            while (_rice >= 5 && (_egg > 0 || _meat > 0 || _bean > 0))
            {
                bool handled = false;
                foreach (int makeid in _getGiftSerial)
                {
                    if (makeid == 3) { if (_egg > 0) { makeZongzi(protocol, logger, 3, ref _rice, ref _bean, ref _meat, ref _egg, ref _ricebean, ref _ricemeat, ref _riceegg); handled = true; break; } }
                    else if (makeid == 2) { if (_meat > 0) { makeZongzi(protocol, logger, 2, ref _rice, ref _bean, ref _meat, ref _egg, ref _ricebean, ref _ricemeat, ref _riceegg); handled = true; break; } }
                    else if (makeid == 1) { if (_bean > 0) { makeZongzi(protocol, logger, 1, ref _rice, ref _bean, ref _meat, ref _egg, ref _ricebean, ref _ricemeat, ref _riceegg); handled = true; break; } }
                }
                if (!handled) break;
            }
            // eat
            while (_ricebean > 0 || _ricemeat > 0 || _riceegg > 0)
            {
                if (_riceegg > 0) eatZongzi(protocol, logger, 3, ref _ricebean, ref _ricemeat, ref _riceegg);
                else if (_ricemeat > 0) eatZongzi(protocol, logger, 2, ref _ricebean, ref _ricemeat, ref _riceegg);
                else if (_ricebean > 0) eatZongzi(protocol, logger, 1, ref _ricebean, ref _ricemeat, ref _riceegg);
                else break;
            }

            return 0;
        }
        public void makeZongzi(ProtocolMgr protocol, ILogger logger, int dragonType, ref int _rice, ref int _bean, ref int _meat, ref int _egg,
            ref int _ricebean, ref int _ricemeat, ref int _riceegg)
        {
            string url = "/root/giftEvent!makeZongzi.action";
            string data = "dragonType=" + dragonType;
            string makething = "";
            if (dragonType == 1) makething = "豆沙包";
            else if (dragonType == 2) makething = "鲜肉包";
            else if (dragonType == 3) makething = "蛋黄包";
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "制作" + makething);
            if (result == null || !result.CmdSucceed) return;
            // <results><state>1</state><message></message></results>
            if (dragonType == 1)
            {
                _ricebean++;
                _bean--;
            }
            else if (dragonType == 2)
            {
                _ricemeat++;
                _meat--;
            }
            else if (dragonType == 3)
            {
                _riceegg++;
                _egg--;
            }
            _rice -= 5;
            logInfo(logger, String.Format("成功制作一个{0}", makething));
        }
        public void eatZongzi(ProtocolMgr protocol, ILogger logger, int dragonType, ref int _ricebean, ref int _ricemeat, ref int _riceegg)
        {
            string url = "/root/giftEvent!eatZongzi.action";
            string data = "dragonType=" + dragonType;
            string eatthing = "";
            if (dragonType == 1) eatthing = "豆沙包";
            else if (dragonType == 2) eatthing = "鲜肉包";
            else if (dragonType == 3) eatthing = "蛋黄包";
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "吃掉" + eatthing);
            if (result == null || !result.CmdSucceed) return;
            XmlDocument xml = result.CmdResult;
            string desc = "";
            if (dragonType == 1)
            {
                _ricebean--;
                //<results><state>1</state><reward><copper>243846</copper></reward></results>
                int copper = 0;
                XmlNode copper_node = xml.SelectSingleNode("/results/reward/copper");
                if (copper_node != null) Int32.TryParse(copper_node.InnerText, out copper);
                desc = String.Format("成功吃掉一个{0}, 银币+{1}", eatthing, copper);
            }
            else if (dragonType == 2)
            {
                _ricemeat--;
                //<results><state>1</state>
                //  <reward><troopchip>
                //      <goodsid>156010</goodsid><goodsname>落魂冥灯碎片</goodsname><num>2</num><goodsquality>6</goodsquality>
                //  </troopchip></reward>
                //</results>
                string goodsname = ""; int goodsnum = 0;
                XmlNode goodsname_node = xml.SelectSingleNode("/results/reward/troopchip/goodsname");
                if (goodsname_node != null) goodsname = goodsname_node.InnerText;

                XmlNode goodsnum_node = xml.SelectSingleNode("/results/reward/troopchip/num");
                if (goodsnum_node != null) Int32.TryParse(goodsnum_node.InnerText, out goodsnum);

                desc = String.Format("成功吃掉一个{0}, 获得{1}*{2}", eatthing, goodsname, goodsnum);
            }
            else if (dragonType == 3)
            {
                _riceegg--;
                //<results><state>1</state><reward><baoshi>8</baoshi></reward></results>
                int gem = 0;
                XmlNode gem_node = xml.SelectSingleNode("/results/reward/baoshi");
                if (gem_node != null) Int32.TryParse(gem_node.InnerText, out gem);
                desc = String.Format("成功吃掉一个{0}, 宝石+{1}", eatthing, gem);
            }
            logInfo(logger, desc);
        }
        #endregion

        #region arch event
        private int upgradeTreasure(ProtocolMgr protocol, ILogger logger, ref int _currentTreasureQuality, int _currentUpgradeCostGold)
        {
            string url = "/root/archEvent!refreshArchTreasure.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "升级考古地图");
            if (result == null) return 1;
            if (!result.CmdSucceed) return 2;
            string[] colors = new string[] { "", "白色", "蓝色", "绿色", "黄色", "红色", "紫色", };
            XmlDocument xml = result.CmdResult;

            XmlNode quality_node = xml.SelectSingleNode("/results/playerarchinfo/treasurequality");
            if (quality_node != null) Int32.TryParse(quality_node.InnerText, out _currentTreasureQuality);

            logInfo(logger, String.Format("升级考古地图成功, 从{0}升级到{1}, 花费{2}金币",
                colors[_currentTreasureQuality], colors[_currentTreasureQuality + 1], _currentUpgradeCostGold));
            _currentTreasureQuality++;
            return 0;
        }
        private int createTeam(ProtocolMgr protocol, ILogger logger, ref bool _alreadyJoinedTeam)
        {
            string url = "/root/archEvent!createArchTeam.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "创建考古队伍");
            if (result == null) return 1;
            if (!result.CmdSucceed) return 2;
            XmlDocument xml = result.CmdResult;
            //<results><state>1</state></results>
            _alreadyJoinedTeam = true;
            logInfo(logger, "创建考古队伍成功");
            return 0;
        }
        private int leftTeam(ProtocolMgr protocol, ILogger logger, ref bool _alreadyJoinedTeam)
        {
            string url = "/root/archEvent!leftTeam.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "离开考古队伍");
            if (result == null) return 1;
            if (!result.CmdSucceed) return 2;
            XmlDocument xml = result.CmdResult;
            //<results><state>1</state></results>
            logInfo(logger, "离开考古队伍");
            _alreadyJoinedTeam = false;
            return 0;
        }
        private int kickPlayer(ProtocolMgr protocol, ILogger logger, int type)
        {
            string url = "/root/archEvent!kickPlayer.action";
            string data = "type=" + type;
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "踢出考古玩家");
            if (result == null) return 1;
            if (!result.CmdSucceed) return 2;
            XmlDocument xml = result.CmdResult;
            //<results><state>1</state></results>
            logInfo(logger, "踢出不符合条件的考古玩家");
            return 0;
        }
        private ArchTeam tryFindTeam(ProtocolMgr protocol, ILogger logger, List<ArchTeam> _curentTeams, 
            int _currentTreasureType, int _currentTreasureQuality, bool _onlySameColorTeam)
        {
            foreach (ArchTeam team in _curentTeams)
            {
                if (team == null || team.types == null || team.types == "") continue;
                string[] typearray = team.types.Split(',');
                if (typearray[_currentTreasureType - 1] != "0") continue;
                if (_onlySameColorTeam)
                {
                    bool is_samecolor = false;
                    string[] quality_array = team.qualities.Split(',');
                    foreach (string str in quality_array)
                    {
                        if (str == null || str.Length == 0) continue;
                        int q = 1000;
                        Int32.TryParse(str, out q);
                        if (q == _currentTreasureQuality)
                        {
                            is_samecolor = true;
                            break;
                        }
                    }
                    if (is_samecolor) { return team; }
                }
                else return team;
            }
            return null;
        }
        /// <summary>
        /// 0=success, 1=http error, 2=no more pieces, 3=something wrong and need half an hour later to continue, 10=cmd error
        /// </summary>
        /// <returns></returns>
        public int getArchInfo(ProtocolMgr protocol, ILogger logger, ref int gold_available, bool _onlySameColorTeam,
            bool _selfCreateTeam, string _upgrades, ref string _lastMemberName, bool only_get_info=false)
        {
            int _treasurenum = 0, _currentTreasureType = 0, _currentTreasureQuality = 0, _currentUpgradeCostGold = 0;
            bool _alreadyJoinedTeam = false, _teamCreatedByMe = false, _selfTeamReady = false;

            #region get info
            string url = "/root/archEvent!getArchInfo.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "获取考古信息");
            if (result == null) return 1;
            if (!result.CmdSucceed) return 10;
            XmlDocument xml = result.CmdResult;

            XmlNode archinfo_node = xml.SelectSingleNode("/results/playerarchinfo");
            if (archinfo_node != null)
            {
                XmlNodeList archinfo_childs = archinfo_node.ChildNodes;
                foreach (XmlNode child in archinfo_childs)
                {
                    if (child.Name == "treasurenum") Int32.TryParse(child.InnerText, out _treasurenum);
                    else if (child.Name == "treasuretype") Int32.TryParse(child.InnerText, out _currentTreasureType);
                    else if (child.Name == "treasurequality") Int32.TryParse(child.InnerText, out _currentTreasureQuality);
                    else if (child.Name == "upgradecost") Int32.TryParse(child.InnerText, out _currentUpgradeCostGold);
                }
            }
            List<ArchTeam> _currentTeams = new List<ArchTeam>();
            XmlNodeList teamlist_nodes = xml.SelectNodes("/results/alltinfo/tinfo");
            foreach (XmlNode teamlist_node in teamlist_nodes)
            {
                XmlNodeList childs = teamlist_node.ChildNodes;
                ArchTeam team = new ArchTeam();
                foreach (XmlNode child in childs)
                {
                    if (child.Name == "teamid") team.teamid = child.InnerText;
                    else if (child.Name == "pname") team.teamname = child.InnerText;
                    else if (child.Name == "nation") team.nation = Int32.Parse(child.InnerText);
                    else if (child.Name == "types") team.types = child.InnerText;
                    else if (child.Name == "quas") team.qualities = child.InnerText;
                }
                if (team.teamid != null || team.teamid != "") _currentTeams.Add(team);
            }
            XmlNode selfteam_node = xml.SelectSingleNode("/results/selfteam");
            if (selfteam_node != null)
            {
                _alreadyJoinedTeam = true;
                ArchMember self = null, other_member = null;
                XmlNodeList members = selfteam_node.SelectNodes("member");
                foreach (XmlNode member_node in members)
                {
                    ArchMember m = new ArchMember();
                    XmlNodeList child_nodes = member_node.ChildNodes;
                    foreach (XmlNode child in child_nodes)
                    {
                        if (child.Name == "name") m.name = child.InnerText;
                        else if (child.Name == "quality") m.quality = Int32.Parse(child.InnerText);
                        else if (child.Name == "type") m.type = Int32.Parse(child.InnerText);
                        else if (child.Name == "state") m.state = child.InnerText.Equals("1");
                        else if (child.Name == "creater") m.creater = child.InnerText.Equals("1");
                        else if (child.Name == "self") m.self = child.InnerText.Equals("1");
                    }
                    if (m.self) self = m;
                    else other_member = m;
                }
                if (self.creater) _teamCreatedByMe = true;
                else _teamCreatedByMe = false;

                if (other_member == null || other_member.name == "") // 还没有其他队友
                {
                    _selfTeamReady = false;
                }
                else // 已经有了队友
                {
                    // 如果队友的颜色与自己不一样, 那么踢掉他
                    if (other_member.quality != self.quality)
                    {
                        if (_teamCreatedByMe)
                        {
                            logInfo(logger, String.Format("队友[{0}]与我品质不同, 将踢掉他", other_member.name));
                            kickPlayer(protocol, logger, other_member.type);
                            _selfTeamReady = false;
                        }
                        else
                        {
                            //什么也不干
                            _selfTeamReady = false;
                        }
                    }
                    else
                    {
                        if (other_member.state)
                        {
                            _selfTeamReady = true;
                        }
                        else
                        {
                            _selfTeamReady = false;
                            if (_teamCreatedByMe)
                            {
                                // 如果队友没有ready, 查看是否是上一次查询时的队友, 如果是, 那么踢掉他, 否则, 记录下他, 
                                if (_lastMemberName != "" && _lastMemberName.Equals(other_member.name))
                                {
                                    // 他还没有ready, 踢掉他
                                    logInfo(logger, String.Format("队友[{0}]检查2次仍然不准备, 将踢掉他", other_member.name));
                                    kickPlayer(protocol, logger, other_member.type);
                                }
                                else
                                {
                                    _lastMemberName = other_member.name;
                                }
                            }
                            else
                            {
                                // 什么也不干
                            }
                        }
                    }
                }
            }

            XmlNode stone_node = xml.SelectSingleNode("/results/rewardcount");
            XmlNode gem_node = xml.SelectSingleNode("/results/extrarewardcount");
            int stone_got = 0, gem_got = 0;
            if (stone_node != null) Int32.TryParse(stone_node.InnerText, out stone_got);
            if (gem_node != null) Int32.TryParse(gem_node.InnerText, out gem_got);
            if (stone_got > 0) logInfo(logger, String.Format("考古完成, 玉石+{0}, 宝石+{1}", stone_got, gem_got));
            #endregion

            if (only_get_info) return 0;

            if (_treasurenum == 0) return 2;
            if (_currentTreasureType == 0) return 3;
            if (_alreadyJoinedTeam)
            {
                if (_selfCreateTeam)
                {
                    if (!_teamCreatedByMe)
                    {
                        leftTeam(protocol, logger, ref _alreadyJoinedTeam);
                        return 0;
                    }
                    else
                    {
                        if (_selfTeamReady)
                        {
                            _lastMemberName = "";
                            doReady(protocol, logger);
                            getArchInfo(protocol, logger, ref gold_available, _onlySameColorTeam,_selfCreateTeam, _upgrades, ref _lastMemberName, true);
                            return 0;
                        }
                        else
                        {
                            return 0;
                        }
                    }
                }
                else
                {
                    if (_teamCreatedByMe) leftTeam(protocol, logger, ref _alreadyJoinedTeam);
                    return 0;
                }
            }
            // 查看是否需要升级
            string qstr = _currentTreasureQuality.ToString();
            if (_upgrades.Contains(qstr))
            {
                // 看需要升级几次, 紫色=6
                int count = 6 - _currentTreasureQuality;
                for (int i = 0; i < count; i++)
                {
                    int tmp = _currentTreasureQuality;
                    if (gold_available >= _currentUpgradeCostGold)
                    {
                        int up_ok = upgradeTreasure(protocol, logger, ref _currentTreasureQuality, _currentUpgradeCostGold);
                        if (up_ok > 0) { logInfo(logger, "升级失败, 下个半小时后继续"); return 3; }
                        if (tmp == _currentTreasureQuality) _currentTreasureQuality++;
                    }
                }
            }
            if (_selfCreateTeam)
            {
                int create_result = createTeam(protocol, logger, ref _alreadyJoinedTeam);
                if (create_result == 2) return 10;
                return 0;
            }
            else
            {
                ArchTeam team = tryFindTeam(protocol, logger, _currentTeams, _currentTreasureType, _currentTreasureQuality, _onlySameColorTeam);
                if (team == null) return 0;
                if (joinTeam(protocol, logger, team.teamid, team.teamname))
                {
                    doReady(protocol, logger);
                    getArchInfo(protocol, logger, ref gold_available, _onlySameColorTeam, _selfCreateTeam, _upgrades, ref _lastMemberName, true);
                }
            }
            return 0;
        }
        public bool joinTeam(ProtocolMgr protocol, ILogger logger, string teamId, string leader)
        {
            string url = "/root/archEvent!joinTeam.action";
            string data = "teamId=" + teamId;
            string desc = String.Format("加入[{0}]的考古队伍, 队伍id=[{1}]", leader, teamId);
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, desc);
            if (result == null || !result.CmdSucceed) return false;
            logInfo(logger, desc);
            return true;
        }
        public bool doReady(ProtocolMgr protocol, ILogger logger)
        {
            string url = "/root/archEvent!ready.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "考古活动准备");
            if (result == null || !result.CmdSucceed) return false;
            return true;
        }
        private class ArchTeam
        {
            //<tinfo>
            //    <teamid>402823d8410681c801412fffbe5d5e6b</teamid>
            //    <pname>天下贼</pname>
            //    <nation>2</nation>
            //    <types>1,1,0</types>
            //    <quas>1,1,0</quas>
            //</tinfo>
            public string teamid;
            public string teamname;
            public int nation;
            public string types;
            public string qualities;
        }
        private class ArchMember
        {
            //<member>
            //    <name>背水奋战</name>
            //    <quality>5</quality>
            //    <type>2</type>
            //    <state>1</state>
            //    <creater>1</creater>
            //    <self>1</self>
            //</member>
            public string name;
            public int quality;
            public int type;
            public bool state;
            public bool creater;
            public bool self;
        }
        #endregion

        #region treasure game

        #region normal treasure game
        /// <summary>
        /// 0=success, 1=http error, 2=no games now, 3=no games today 10=cmd error
        /// </summary>
        /// <returns></returns>
        public int handleTreasureGameInfo(ProtocolMgr protocol, ILogger logger, User user, string _open_box_type, string _gold_move_box_type, int _minGoldSteps,
            ref int gold_available)
        {
            List<GameGrid> _grids = new List<GameGrid>();
            int _game_remains = 0, _onlinegame_remains = 0, _player_pos_now = 0;

            string url = "/root/treasureGame!getGameInfo.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "获取古城探宝信息");
            if (result == null) return 1;
            if (!result.CmdSucceed) return 10;
            XmlDocument xml = result.CmdResult;

            XmlNode dices_node = xml.SelectSingleNode("/results/dice");
            if (dices_node != null) Int32.TryParse(dices_node.InnerText, out _game_remains);
            else _game_remains = 0;

            XmlNode onlineRemains_node = xml.SelectSingleNode("/results/remainonlinedice");
            if (onlineRemains_node != null) Int32.TryParse(onlineRemains_node.InnerText, out _onlinegame_remains);
            else _onlinegame_remains = 0;

            XmlNode playerpos_node = xml.SelectSingleNode("/results/playerpos");
            if (playerpos_node != null) Int32.TryParse(playerpos_node.InnerText, out _player_pos_now);
            else _player_pos_now = 0;

            renderGrids(logger, xml, _grids);

            XmlNode question_node = xml.SelectSingleNode("/results/question");
            if (question_node != null)
            {
                handleQuestion(protocol, logger, question_node, null);
            }

            //start do things
            if (_game_remains == 0)
            {
                if (_player_pos_now == 0 || _player_pos_now == 27)
                {
                    if (_onlinegame_remains == 0) return 3;
                    else return 2;
                }
            }
            logInfo(logger, String.Format("获得古城寻宝信息, 当前还剩寻宝次数{0}次, 玩家目前位于{1}位置", _game_remains, _player_pos_now));
            if (_player_pos_now == _grids.Count)
            {
                if (!playAgainTreasure(protocol, logger, _grids)) return 0;
            }

            while (_player_pos_now < 27)
            {
                int diceNext = getNextStepDice(false, user, gold_available, _gold_move_box_type, _minGoldSteps, _player_pos_now, _grids);
                useDiceTreasure(protocol, logger, diceNext, _open_box_type, gold_available, _grids, ref _player_pos_now);
            }
            return 0;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="diceId">0=随机, 1=2金币只走一点, 2=1金币只走2点</param>
        /// <returns></returns>
        private bool useDiceTreasure(ProtocolMgr protocol, ILogger logger, int diceId, string _open_box_type, int gold_available, List<GameGrid> _grids, ref int _player_pos_now)
        {
            string url = "/root/treasureGame!useDice.action";
            string data = "controlDiceId=" + diceId;
            string desc = String.Format("古城探宝掷筛子, 玩家位置在{0}, ", _player_pos_now);
            if (diceId == 1) desc += "使用2金币遥控筛子,只走一步, ";
            else if (diceId == 2) desc += "使用1金币遥控筛子,只走两步, ";
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, desc);
            if (result == null || !result.CmdSucceed) return false;
            XmlDocument xml = result.CmdResult;
            desc += handleDiceResult(protocol, logger, xml, _grids, ref _player_pos_now, ref gold_available, ref _open_box_type, null);
            logInfo(logger, desc);
            return true;
        }
        private bool playAgainTreasure(ProtocolMgr protocol, ILogger logger, List<GameGrid> _grids)
        {
            string url = "/root/treasureGame!playAgain.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "开启新一轮古城探宝");
            if (result == null || !result.CmdSucceed) return false;
            XmlDocument xml = result.CmdResult;
            renderGrids(logger, xml, _grids);
            logInfo(logger, "开启新一轮古城探宝");
            return true;
        }
        /// <summary>
        /// 0=success, 1=http failure, 2=all super games done, 10=no this activity
        /// </summary>
        /// <param name="protocol"></param>
        /// <param name="logger"></param>
        /// <param name="gold_available"></param>
        /// <param name="use_ticket_type"></param>
        /// <param name="gold_to_end"></param>
        /// <returns></returns>
        public int handleNewTreasureGames(ProtocolMgr protocol, ILogger logger, int gold_available, int use_ticket_type, bool gold_to_end)
        {
            // first get game info
            int ticket_remains = 0, running_id = 0, now_pos = 0, max_pos = 0;
            string url = "/root/treasureGame!getNewGameInfo.action";
            string data = "newId=0";
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "获取超级探宝信息");
            if (result == null) return 1;
            if (!result.CmdSucceed) return 10;
            XmlDocument xml = result.CmdResult;

            XmlNode ticket_node = xml.SelectSingleNode("/results/superticket");
            if (ticket_node != null) Int32.TryParse(ticket_node.InnerText, out ticket_remains);
            XmlNode id_node = xml.SelectSingleNode("/results/id");
            if (id_node != null) Int32.TryParse(id_node.InnerText, out running_id);
            XmlNode newpos_node = xml.SelectSingleNode("/results/newpos");
            if (newpos_node != null) Int32.TryParse(newpos_node.InnerText, out now_pos);
            XmlNode maxnewpos_node = xml.SelectSingleNode("/results/maxnewpos");
            if (maxnewpos_node != null) Int32.TryParse(maxnewpos_node.InnerText, out max_pos);

            if (ticket_remains == 0 && running_id == 0) return 2;

            int gold_available_now = gold_available;
            int game_free_dice_remains = 0, player_now_pos = 0, buy_dice_cost = 10;
            bool game_can_continue = false;
            if (running_id > 0) // 正在一轮超级探宝中
            {
                //do treasure game
                int info_result = getNewGameInfo(protocol, logger, running_id, out game_free_dice_remains, out player_now_pos, out buy_dice_cost, out max_pos);
                if (info_result > 0) return info_result;
                if (game_free_dice_remains > 0 || gold_to_end) game_can_continue = true;
                else
                {
                    info_result = leaveSuperGame(protocol, logger);
                    if (info_result > 0) return info_result;
                }
            }
            if (!game_can_continue)
            {
                if (ticket_remains > 0)
                {
                    int info_result = getNewGameInfo(protocol, logger, use_ticket_type, out game_free_dice_remains, out player_now_pos, out buy_dice_cost, out max_pos);
                    if (info_result > 0) return info_result;
                    game_can_continue = true;
                }
            }
            if (game_can_continue)
            {
                while (player_now_pos < max_pos)
                {
                    int use_result = 0;
                    if (game_free_dice_remains > 0)
                    {
                        use_result = useNewDice(protocol, logger, buy_dice_cost, false, out game_free_dice_remains, out player_now_pos);
                        if (use_result > 0) return 1;
                    }
                    else
                    {
                        if (!gold_to_end || gold_available_now < buy_dice_cost)
                        {
                            int leave_result = leaveSuperGame(protocol, logger);
                            if (leave_result > 0) return leave_result;
                            break;
                        }
                        else
                        {
                            use_result = useNewDice(protocol, logger, buy_dice_cost, true, out game_free_dice_remains, out player_now_pos);
                            if (use_result > 0) return 1;
                            gold_available_now -= buy_dice_cost;
                        }
                    }
                }
            }
            
            return 0;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="protocol"></param>
        /// <param name="logger"></param>
        /// <param name="gameId">0=界面, 1=玉石, 2=宝石, 3=兵器</param>
        /// <returns></returns>
        public int getNewGameInfo(ProtocolMgr protocol, ILogger logger, int gameId, out int game_free_dice_remains , out int player_now_pos, 
            out int buy_dice_cost, out int max_pos)
        {
            game_free_dice_remains = 0; player_now_pos = 0; buy_dice_cost = 10; max_pos = 20;
            if (gameId < 1 || gameId > 3) return 10;
            string url = "/root/treasureGame!getNewGameInfo.action";
            string data = "newId=" + gameId;
            string[] names = new string[] {"探宝信息", "玉石探宝", "宝石探宝", "兵器探宝" };
            string desc = "开启超级探宝之" + names[gameId];
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, desc);
            if (result == null) return 1;
            if (!result.CmdSucceed) return 10;
            XmlDocument xml = result.CmdResult;

            XmlNode dice_node = xml.SelectSingleNode("/results/newdice");
            if (dice_node != null) Int32.TryParse(dice_node.InnerText, out game_free_dice_remains);
            XmlNode pos_node = xml.SelectSingleNode("/results/playerpos");
            if (pos_node != null) Int32.TryParse(pos_node.InnerText, out player_now_pos);
            XmlNode cost_node = xml.SelectSingleNode("/results/buydicecost");
            if (cost_node != null) Int32.TryParse(cost_node.InnerText, out buy_dice_cost);

            XmlNodeList grid_nodes = xml.SelectNodes("/results/grid");
            if (grid_nodes != null) max_pos = grid_nodes.Count;

            logInfo(logger, String.Format("{0}, 还剩免费骰子[{1}]个, 当前位置在[{2}]", desc, game_free_dice_remains, player_now_pos));
            return 0;
        }
        private int leaveSuperGame(ProtocolMgr protocol, ILogger logger)
        {
            string url = "/root/treasureGame!leaveNewGame.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "离开超级探宝");
            if (result == null) return 1;
            if (!result.CmdSucceed) return 10;
            XmlDocument xml = result.CmdResult;
            logInfo(logger, "离开超级探宝");
            return 0;
        }
        /// <summary>
        /// 0=success, 1=http failure, 10=other error(possible no gold)
        /// </summary>
        /// <param name="protocol"></param>
        /// <param name="logger"></param>
        /// <param name="useGold"></param>
        /// <param name="game_free_dice_remains"></param>
        /// <param name="player_now_pos"></param>
        /// <returns></returns>
        public int useNewDice(ProtocolMgr protocol, ILogger logger, int buy_dice_cost, bool useGold, out int game_free_dice_remains, out int player_now_pos)
        {
            game_free_dice_remains = 0; player_now_pos = 0;
            string url = "/root/treasureGame!useNewDice.action";
            string desc = "超级探宝掷骰子";
            if (useGold)
            {
                url = "/root/treasureGame!buyNewGameDice.action";
                desc = String.Format("超级探宝购买骰子, 花费{0}金币", buy_dice_cost);
            }
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, desc);
            if (result == null) return 1;
            if (!result.CmdSucceed) return 10;
            XmlDocument xml = result.CmdResult;

            int dice_num = 0;
            XmlNode dicenum_node = xml.SelectSingleNode("/results/dicenum");
            if (dicenum_node != null) Int32.TryParse(dicenum_node.InnerText, out dice_num);
            XmlNode dice_node = xml.SelectSingleNode("/results/newdice");
            if (dice_node != null) Int32.TryParse(dice_node.InnerText, out game_free_dice_remains);
            XmlNode pos_node = xml.SelectSingleNode("/results/playerpos");
            if (pos_node != null) Int32.TryParse(pos_node.InnerText, out player_now_pos);

            StringBuilder sb = new StringBuilder();
            sb.Append(String.Format("{0}, 扔出了[{1}]点, 当前位置[{2}], 获得奖励: ", desc, dice_num, player_now_pos));
            XmlNodeList reward_nodes = xml.SelectNodes("/results/reward");
            foreach (XmlNode reward_node in reward_nodes)
            {
                if (reward_node == null || !reward_node.HasChildNodes) continue;
                string pos = "", num = "", name = "";
                XmlNodeList childs = reward_node.ChildNodes;
                foreach (XmlNode child in childs)
                {
                    if (child.Name == "pos") pos = child.InnerText;
                    else if (child.Name == "rewardnum") num = child.InnerText;
                    else if (child.Name == "rewardname") name = child.InnerText;
                }
                sb.Append(String.Format("{0}+{1} ", name,num));
            }
            logInfo(logger, sb.ToString());

            return 0;
        }
        #endregion

        #region daily treasure game
        /// <summary>
        /// 0=success, 1=http error, 2=no games now, 3=no silver to open game, 10=cmd error
        /// </summary>
        /// <returns></returns>
        public int handleDailyTreasureGameInfo(ProtocolMgr protocol, ILogger logger, User user, string _open_box_type, string _gold_move_box_type, int _minGoldSteps, 
            ref int gold_available, ref int silver_available)
        {
            bool _canGetEventDice = false; 
            int _dailyDiceRemains = 0, _eventDiceRemains = 0, _player_pos_now = 0;

            string url = "/root/dayTreasureGame!getAllGameInfo.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "获取日常探宝信息");
            if (result == null) return 1;
            if (!result.CmdSucceed) return 10;
            XmlDocument xml = result.CmdResult;

            XmlNode can_getevent_dice_node = xml.SelectSingleNode("/results/cangeteventdice");
            if (can_getevent_dice_node != null) _canGetEventDice = can_getevent_dice_node.InnerText == "1";
            else _canGetEventDice = false;

            XmlNode dice_remains_node = xml.SelectSingleNode("/results/dice");
            if (dice_remains_node != null) Int32.TryParse(dice_remains_node.InnerText, out _dailyDiceRemains);

            XmlNode event_dice_remains_node = xml.SelectSingleNode("/results/eventdice");
            if (event_dice_remains_node != null) Int32.TryParse(event_dice_remains_node.InnerText, out _eventDiceRemains);

            _dailyDiceRemains += _eventDiceRemains;

            List<TGame> _dailyGames = new List<TGame>();
            TGame _doing_game = null; TGame _mostValuable_game = null;

            XmlNodeList game_nodes = xml.SelectNodes("/results/game");
            foreach (XmlNode game_node in game_nodes)
            {
                if (game_node == null || !game_node.HasChildNodes) continue;
                TGame game = new TGame();
                XmlNodeList childs = game_node.ChildNodes;
                foreach (XmlNode child in childs)
                {
                    if (child.Name == "tid") game.tid = Int32.Parse(child.InnerText);
                    else if (child.Name == "powername") game.powername = child.InnerText;
                    else if (child.Name == "coppercost") game.coppercost = Int32.Parse(child.InnerText);
                    else if (child.Name == "open") game.open = Int32.Parse(child.InnerText);
                    else if (child.Name == "maxpos") game.maxpos = Int32.Parse(child.InnerText);
                    else if (child.Name == "pos") game.pos = Int32.Parse(child.InnerText);
                }
                if (game.open == 0) continue;
                if (game.maxpos > 0) _doing_game = game;
                if (_mostValuable_game == null || _mostValuable_game.tid < game.tid) _mostValuable_game = game;
                _dailyGames.Add(game);
            }

            //start do things
            if (_dailyGames.Count == 0) return 2;
            if (_canGetEventDice) getEventDiceDailyTreasure(protocol, logger);
            if (_dailyDiceRemains > 0)
            {
                logInfo(logger, String.Format("获得日常探宝信息, 当前还剩寻宝次数{0}次, 玩家目前位于{1}位置",
                    _dailyDiceRemains, _player_pos_now));
            }
            List<GameGrid> _grids = new List<GameGrid>();
            if (_doing_game != null)
            {
                int info_result = getGameInfoDailyTreasure(protocol, logger,_doing_game.tid, _grids, ref _player_pos_now, _doing_game);
                if (info_result == 1) return 1;
                do_game_DailyTreasure(protocol, logger, user, _open_box_type, _gold_move_box_type, _minGoldSteps, ref gold_available, _grids, ref _player_pos_now, ref _doing_game);
            }
            if (_dailyDiceRemains == 0)
            {
                if (_doing_game == null) return 2;
            }
            else if (_dailyDiceRemains > 0)
            {
                if (_mostValuable_game == null) return 1;
                if (silver_available < _mostValuable_game.coppercost) return 3;
                
                int open_result = openDailyTreasureBySilver(protocol, logger, _mostValuable_game.tid, _dailyGames, ref _player_pos_now, out _doing_game);
                if (open_result == 0)
                {
                    do_game_DailyTreasure(protocol, logger, user, _open_box_type, _gold_move_box_type, _minGoldSteps, ref gold_available, _grids, ref _player_pos_now, ref _doing_game);
                }
            }
            return 0;
        }
        private void do_game_DailyTreasure(ProtocolMgr protocol, ILogger logger, User user, string _open_box_type, string _gold_move_box_type, int _minGoldSteps, ref int gold_available, 
            List<GameGrid> _grids, ref int _player_pos_now, ref TGame _doing_game)
        {
            while (_player_pos_now < _doing_game.maxpos)
            {
                int diceNext = getNextStepDice(true, user, gold_available, _gold_move_box_type, _minGoldSteps, _player_pos_now, _grids);
                if (!useDiceDailyTreasure(protocol, logger, diceNext, _doing_game.tid, _grids, ref _player_pos_now, ref gold_available, ref _open_box_type, _doing_game)) break;
            }
        }
        private int getEventDiceDailyTreasure(ProtocolMgr protocol, ILogger logger)
        {
            string url = "/root/dayTreasureGame!getEventDice.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "获取每日探宝免费令");
            if (result == null) return 1;
            if (!result.CmdSucceed) return 2;
            //<results><state>1</state><eventdice>5</eventdice></results>
            return 0;
        }
        private int openDailyTreasureBySilver(ProtocolMgr protocol, ILogger logger, int tid,List<TGame> _dailyGames, ref int _player_pos_now, out TGame _doing_game)
        {
            _doing_game = null;
            string url = "/root/dayTreasureGame!getGameInfo.action";
            string data = "tid=" + tid;
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "开启探宝地图");
            if (result == null) return 1;
            if (!result.CmdSucceed) return 2;
            foreach (TGame game in _dailyGames)
            {
                if (game.tid == tid)
                {
                    _doing_game = game;
                    _player_pos_now = 0;
                    break;
                }
            }
            XmlDocument xml = result.CmdResult;
            return 0;
        }
        private bool confirmFateDailyTreasure(ProtocolMgr protocol, ILogger logger, int tid, int fateId, ref int _player_pos_now)
        {
            string url = "/root/dayTreasureGame!useDice.action";
            string data = String.Format("useFateDice={0}&tid={1}", fateId, tid);
            string desc = String.Format("面对命运筛子, 我选择{0}, 玩家位置在{1}", fateId == 1 ? "相信命运" : "自己掌握", _player_pos_now);
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, desc);
            if (result == null || !result.CmdSucceed) return false;
            XmlDocument xml = result.CmdResult;
            return true;
        }
        /// <summary>
        /// 1=http error, 2=cmd error
        /// </summary>
        /// <returns></returns>
        private int getGameInfoDailyTreasure(ProtocolMgr protocol, ILogger logger, int tid, List<GameGrid> _grids, ref int _player_pos_now, TGame _doing_game)
        {
            string url = "/root/dayTreasureGame!getGameInfo.action";
            string data = "tid=" + tid;
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "获取日常探宝信息");
            if (result == null) return 1;
            if (!result.CmdSucceed) return 2;
            XmlDocument xml = result.CmdResult;

            XmlNode playerpos_node = xml.SelectSingleNode("/results/playerpos");
            if (playerpos_node != null) Int32.TryParse(playerpos_node.InnerText, out _player_pos_now);
            else _player_pos_now = 0;

            renderGrids(logger, xml, _grids);

            XmlNode question_node = xml.SelectSingleNode("/results/question");
            if (question_node != null)
            {
                handleQuestion(protocol, logger, question_node, _doing_game);
            }

            return 0;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="diceId">0=随机, 1=2金币只走一点, 2=1金币只走2点</param>
        /// <returns></returns>
        private bool useDiceDailyTreasure(ProtocolMgr protocol, ILogger logger, int diceId, int tid, List<GameGrid> _grids, ref int _player_pos_now,
            ref int gold_available, ref string _open_box_type, TGame _doing_game)
        {
            string url = "/root/dayTreasureGame!useDice.action";
            string data = String.Format("controlDiceId={0}&tid={1}", diceId, tid);
            string desc = String.Format("日常探宝掷筛子, 玩家位置在{0}, ", _player_pos_now);
            if (diceId == 1) desc += "使用2金币遥控筛子,只走一步, ";
            else if (diceId == 2) desc += "使用1金币遥控筛子,只走两步, ";
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, desc);
            if (result == null || !result.CmdSucceed) return false;
            XmlDocument xml = result.CmdResult;
            desc += handleDiceResult(protocol, logger, xml, _grids, ref _player_pos_now, ref gold_available, ref _open_box_type, _doing_game);
            logInfo(logger, desc);
            return true;
        }
        #endregion

        #region treasure game base
        protected List<Question> _question_db = new List<Question>();
        protected string handleDiceResult(ProtocolMgr protocol, ILogger logger, XmlDocument xml, List<GameGrid> _grids, 
            ref int _player_pos_now, ref int gold_available, ref string _open_box_type, TGame _doing_game)
        {
            string desc = "";
            int dice_num = 0;
            XmlNode dice_num_node = xml.SelectSingleNode("/results/dicenum");
            if (dice_num_node != null) Int32.TryParse(dice_num_node.InnerText, out dice_num);

            XmlNodeList nextpos_nodes = xml.SelectNodes("/results/step/nextpos");
            if (nextpos_nodes != null && nextpos_nodes.Count > 0)
            {
                // 最后一个节点保存的数据是最终移动到的数据
                XmlNode nextpos_node = nextpos_nodes.Item(nextpos_nodes.Count - 1);
                if (nextpos_node != null) Int32.TryParse(nextpos_node.InnerText, out _player_pos_now);
            }

            GameGrid currentGrid = _grids[_player_pos_now - 1];

            desc += String.Format("掷出了{0}点, ", dice_num);

            XmlNodeList step_nodes = xml.SelectNodes("/results/step");
            foreach (XmlNode step_node in step_nodes)
            {
                if (step_node == null || !step_node.HasChildNodes) continue;
                XmlNodeList step_subnodes = step_node.ChildNodes;
                string info = "";
                foreach (XmlNode step_subnode in step_subnodes)
                {
                    if (step_subnode.Name == "info")
                    {
                        info = step_subnode.InnerText;
                        if (info.Equals("goldbox"))
                        {
                            int goldcost = 0;
                            XmlNode goldcost_node = xml.SelectSingleNode("/results/step/goldboxcost");
                            if (goldcost_node != null) Int32.TryParse(goldcost_node.InnerText, out goldcost);
                            if (goldcost <= gold_available && (
                                (currentGrid.star == 2 && _open_box_type.Contains("2")) || (currentGrid.star == 3 && _open_box_type.Contains("3")
                                )))
                            {
                                desc += String.Format("运气不错, 碰上了{0}星金宝箱, 需要{1}金币才能开, 犹豫再三, 开了宝箱!! ", currentGrid.star, goldcost);
                                string openbox_result = openBoxOrNot(protocol, logger, true, _doing_game);
                                desc += openbox_result;
                                gold_available -= goldcost;
                            }
                            else
                            {
                                openBoxOrNot(protocol, logger, false, _doing_game);
                                desc += String.Format("运气不好, 碰上了{0}星金宝箱, 需要{1}金币才能开, 不开! 走人~~", currentGrid.star, goldcost);
                            }
                        }
                        else
                        {
                            if (info.Equals("box")) desc += "哇, 我们遇到了不花钱的宝箱耶, ";
                            else if (info.Equals("times")) desc += "天降某种机缘, ";
                            else if (info.Equals("battle")) desc += "打了一架, ";
                            else if (info.Equals("punish")) desc += "天有不测风云, ";
                            else if (info.Equals("move")) desc += "碰到移动神坛, 继续移动==>; ";
                            else if (info.Equals("tree"))
                            {
                                desc += "哇塞, 碰到了摇钱树!!!! ";
                                desc += doShakeTree(protocol, logger, _doing_game);
                            }
                            else if (info.Equals("fin")) desc += "到达终点, ";
                            else if (info.Equals("question"))
                            {
                            }
                        }
                    }
                    else if (step_subnode.Name == "question")
                    {
                        handleQuestion(protocol, logger, step_subnode, _doing_game);
                    }
                    else if (step_subnode.Name == "rewardinfo")
                    {
                        XmlNodeList reward_nodes = step_subnode.ChildNodes;
                        foreach (XmlNode reward_node in reward_nodes)
                        {
                            desc += getRewardName(reward_node);
                        }
                    }
                }
            }
            return desc;
        }
        protected string getRewardName(XmlNode reward_node)
        {
            if (reward_node == null || !reward_node.HasChildNodes) return "";
            XmlNodeList child_nodes = reward_node.ChildNodes;
            int reward_type = 0, reward_num = 0;
            string itemname = "";
            foreach (XmlNode child in child_nodes)
            {
                if (child.Name == "type") Int32.TryParse(child.InnerText, out reward_type);
                else if (child.Name == "num") Int32.TryParse(child.InnerText, out reward_num);
                else if (child.Name == "itemname") itemname = child.InnerText;
            }
            string reward_name = String.Format("[type={0},name={1}]", reward_type, reward_node.InnerXml);
            if (reward_type == 1) reward_name = "银币";
            else if (reward_type == 2) reward_name = "玉石";
            else if (reward_type == 3) reward_name = "333 --- " + reward_node.InnerXml;
            else if (reward_type == 4) reward_name = "444 --- " + reward_node.InnerXml;
            else if (reward_type == 5) reward_name = "宝石";
            else if (reward_type == 6) reward_name = "666 --- " + reward_node.InnerXml;
            else if (reward_type == 7) reward_name = String.Format("兵器[{0}]", itemname);
            else if (reward_type == 8) reward_name = "征收次数";
            else if (reward_type == 9)
            {
                reward_name = "纺织次数";
                //notifyServer("movable");
            }
            else if (reward_type == 10)
            {
                reward_name = "通商次数";
                //notifyServer("movable");
            }
            else if (reward_type == 11) reward_name = "炼化次数";
            else if (reward_type == 12) reward_name = "兵力减少";
            else if (reward_type == 13)
            {
                reward_name = "副本重置卡";
                //notifyServer("res_campaign");
            }
            else if (reward_type == 14) reward_name = "战役双倍卡";
            else if (reward_type == 15) reward_name = "强化暴击卡";
            else if (reward_type == 16) reward_name = "强化打折卡";
            else if (reward_type == 17) reward_name = "兵器提升卡";
            else if (reward_type == 18) reward_name = "兵器暴击卡";
            else if (reward_type == 29) reward_name = "政绩翻倍卡";
            else if (reward_type == 30) reward_name = "征收翻倍卡";
            else if (reward_type == 31) reward_name = "商人召唤卡";
            else if (reward_type == 32) reward_name = "纺织翻倍卡";
            else if (reward_type == 35) return ""; //reward_name = "摇钱树次数";
            else if (reward_type == 36) reward_name = "超级门票";
            return String.Format("{0}{1}{2}", reward_name, reward_num > 0 ? "+" : "", reward_num);
        }
        protected string doShakeTree(ProtocolMgr protocol, ILogger logger, TGame _doing_game)
        {
            string url = "";
            if (_doing_game == null) url = "/root/treasureGame!startShake.action";
            else url = "/root/dayTreasureGame!startShake.action";
            string desc = "摇晃摇钱树, 天灵灵地灵灵~~~~";
            int shake_count = 3;
            com.lover.astd.common.model.ServerResult result;
            XmlDocument xml;
            int count = 0;
            while (shake_count > 0 && count <= 3)
            {
                count++;
                result = protocol.getXml(url, "摇钱树摇钱");
                if (result == null || !result.CmdSucceed) break;

                xml = result.CmdResult;
                //<results><state>1</state><copper>774216</copper><shake>2</shake></results>
                XmlNode silver_node = xml.SelectSingleNode("/results/copper");
                if (silver_node != null) desc += " 银币+" + silver_node.InnerText;
                XmlNode stone_node = xml.SelectSingleNode("/results/bowlder");
                if (stone_node != null) desc += " 玉石+" + stone_node.InnerText;
                XmlNode gem_node = xml.SelectSingleNode("/results/baoshi");
                if (gem_node != null) desc += " 宝石+" + gem_node.InnerText;

                XmlNode num_node = xml.SelectSingleNode("/results/shake");
                if (num_node != null) Int32.TryParse(num_node.InnerText, out shake_count);
                if (shake_count == 0) break;
            }

            return desc;
        }
        protected void handleQuestion(ProtocolMgr protocol, ILogger logger, XmlNode xml, TGame _doing_game)
        {
            int question_num = 0, is_last = 0;
            string question = "", answer1 = "", answer2 = "";

            XmlNode qnum_node = xml.SelectSingleNode("qnum");
            if (qnum_node != null) Int32.TryParse(qnum_node.InnerText, out question_num);
            else question_num = 0;

            XmlNode islast_node = xml.SelectSingleNode("islast");
            if (islast_node != null) Int32.TryParse(islast_node.InnerText, out is_last);
            else is_last = 0;

            XmlNode question_node = xml.SelectSingleNode("q");
            if (question_node != null) question = question_node.InnerText;

            XmlNode answer1_node = xml.SelectSingleNode("a1");
            if (answer1_node != null) answer1 = answer1_node.InnerText;

            XmlNode answer2_node = xml.SelectSingleNode("a2");
            if (answer2_node != null) answer2 = answer2_node.InnerText;

            string url, data;
            int answer_id = getQuestionAnswer(logger, question, answer1, answer2); // 第一个答案为1, 第二个为2
            if (_doing_game == null)
            {
                url = "/root/treasureGame!doQuestion.action";
                data = String.Format("answerId={1}&qnum={0}", question_num, answer_id);
            }
            else
            {
                url = "/root/dayTreasureGame!doQuestion.action";
                data = String.Format("tid={0}&answerId={2}&qnum={1}", _doing_game.tid, question_num, answer_id);
            }
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "探宝回答问题");
            if (result == null || !result.CmdSucceed) return;
            XmlDocument doc = result.CmdResult;

            XmlNode correct_node = doc.SelectSingleNode("/results/correct");
            if (correct_node != null)
            {
                logInfo(logger, String.Format("问题回答{0}", correct_node.InnerText == "1" ? "正确" : "错误"));
            }

            XmlNode qnode = doc.SelectSingleNode("/results/step/question");
            if (qnode != null)
            {
                if (is_last == 0) handleQuestion(protocol, logger, qnode, _doing_game);
                else
                {
                    logInfo(logger, qnode.InnerXml);
                }
            }
            else
            {
                qnode = doc.SelectSingleNode("/results/question");
                if (qnode != null)
                {
                    handleQuestion(protocol, logger, qnode, _doing_game);
                }
                else
                {
                    XmlNode rewardinfo_node = doc.SelectSingleNode("/results/rewardinfo");
                    if (rewardinfo_node != null)
                    {
                        string desc = "答题成功, 获得";
                        XmlNodeList reward_nodes = rewardinfo_node.ChildNodes;
                        foreach (XmlNode reward_node in reward_nodes)
                        {
                            desc += getRewardName(reward_node);
                        }
                        logInfo(logger, desc);
                        //notifyServer("polish");
                    }
                }
            }
        }
        private int getQuestionAnswer(ILogger logger, string question, string answer1, string answer2)
        {
            if (_question_db.Count == 0) initQuestionDb();
            int answer = 1; bool found = false; string desc = "";
            foreach (Question q in _question_db)
            {
                if (q.question.IndexOf(question) >= 0)
                {
                    answer = q.answer; found = true; break;
                }
            }
            if (found)
            {
                desc = String.Format("回答问题:[{0}], 1:[{1}], 2:[{2}], 回答[{3}]", question, answer1, answer2, answer);
                logInfo(logger, desc);
            }
            else
            {
                desc = String.Format("回答问题:[{0}], 1:[{1}], 2:[{2}], 题库未找到, 默认回答1", question, answer1, answer2);
                logInfo(logger, desc);
                logger.logSurprise(desc);
            }

            return answer;
        }
        protected string openBoxOrNot(ProtocolMgr protocol, ILogger logger, bool open, TGame _doing_game)
        {
            string url, data;
            if (_doing_game == null)
            {
                url = "/root/treasureGame!confirmOpenGoldBox.action";
                data = "openGoldBox=" + (open ? "1" : "0");
            }
            else
            {
                url = "/root/dayTreasureGame!confirmOpenGoldBox.action";
                data = String.Format("openGoldBox={0}&tid={1}", (open ? "1" : "0"), _doing_game.tid);
            }
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "探宝打开宝箱");
            if (result == null || !result.CmdSucceed) return "";
            //<results>
            //  <state>1</state>
            //  <rewardinfo>
            //    <reward>
            //      <type>14</type>
            //      <lv>1</lv>
            //      <num>2</num>
            //    </reward>
            //  </rewardinfo>
            //  <notice><![CDATA[先他人一步找到宝箱，打开获得<font color="#94A354">战役双倍卡+2</font> ]]></notice>
            //</results>
            XmlDocument xml = result.CmdResult;
            XmlNodeList reward_nodes = xml.SelectNodes("/results/rewardinfo/reward");
            string desc = "获得 ";
            foreach (XmlNode reward_node in reward_nodes)
            {
                desc += getRewardName(reward_node) + "  ";
            }
            return desc;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="minGoldSteps">距离目前多少步之内使用金币前进, 如果是0, 则不使用金币前进</param>
        /// <param name="openBoxType">打开宝箱类型, 位标识, 00表示不开金币宝箱, 10表示只打开2星, 01表示只打开3星, 11表示打开2星和3星宝箱</param>
        /// <returns>0=随机, 1=2金币只走一点, 2=1金币只走2点</returns>
        protected int getNextStepDice(bool isDaily, User user, int gold_available, string _gold_move_box_type, int _minGoldSteps, int _player_pos_now, List<GameGrid> _grids)
        {
            if (_minGoldSteps <= 0) return 0;
            if (!_gold_move_box_type.Contains("0") && !_gold_move_box_type.Contains("1") &&
                !_gold_move_box_type.Contains("2") && !_gold_move_box_type.Contains("3") &&
                !_gold_move_box_type.Contains("4") && !_gold_move_box_type.Contains("5") &&
                !_gold_move_box_type.Contains("6")) return 0;
            // find next gold box
            int next_goldbox_index = -1, move_index = -1;
            // 如何判断前进两步(daily)和三步(no-daily)的step??
            // 如果move在goldbox之前, 在当前位置之后, 那么move_index会被赋值, 如果在goldbox之后, 则move_index会保持-1, 本次可以不考虑
            for (int i = _player_pos_now, len = _grids.Count; i < len; i++)
            {
                GameGrid grid = _grids[i];
                if (grid == null) continue;
                if (grid.info.Equals("move"))
                {
                    move_index = i + 1;
                }
                else if (grid.info.Equals("box"))
                {
                    if (grid.star == 0 && _gold_move_box_type.Contains("0")) { next_goldbox_index = i + 1; break; }
                    else if (grid.star == 1 && _gold_move_box_type.Contains("1")) { next_goldbox_index = i + 1; break; }
                }
                else if (grid.info.Equals("goldbox"))
                {
                    if (grid.star == 2)
                    {
                        if (_gold_move_box_type.Contains("2")) { next_goldbox_index = i + 1; break; }
                    }
                    else if (grid.star == 3)
                    {
                        if (_gold_move_box_type.Contains("3")) { next_goldbox_index = i + 1; break; }
                    }
                }
                else if (grid.info.Equals("tree"))
                {
                    if (_gold_move_box_type.Contains("4")) { next_goldbox_index = i + 1; break; }
                }
                else if (grid.info.Equals("ticket"))
                {
                    if (_gold_move_box_type.Contains("5")) { next_goldbox_index = i + 1; break; }
                }
                else if (grid.info.Equals("times"))
                {
                    if (isDaily && user._is_new_trade)
                    {
                        if (_gold_move_box_type.Contains("6")) { next_goldbox_index = i + 1; break; }
                    }
                }
            }
            // 如果已经没有宝箱, 那么随便走
            if (next_goldbox_index < 0) return 0;
            // 如果move_index已经赋值, 那么首先判断是否在经过move恰好能够飞到goldbox, 如果是, 那么直接走到move就好
            // 如果不是, 那么判断走到move然后飞到的位置是在goldbox之前还是之后, 如果是之前, 那么可以利用move, 否则, 必须避开move
            // 如果要利用move, 那么当前目标就是走到move
            int step_to_goldbox_nearest = 0;
            if (move_index > 0)
            {
                int move_step = isDaily ? 2 : 3;
                if (next_goldbox_index - move_index == move_step)
                {
                    step_to_goldbox_nearest = move_index - _player_pos_now;
                }
                else if (next_goldbox_index - move_index > move_step)
                {
                    // 如果next_goldbox_index - _player_pos_now > _minGoldSteps, 那么根本不必使用遥控骰子, 直接走就好, 否则使用
                    if (next_goldbox_index - _player_pos_now > _minGoldSteps)
                        step_to_goldbox_nearest = next_goldbox_index - _player_pos_now;
                    else
                        step_to_goldbox_nearest = move_index - _player_pos_now;
                }
                else if (next_goldbox_index - move_index < move_step)
                {
                    // 避开move
                    // 如果当前位置和move距离=1, 那么目标为move+1, 如果距离大于2, 那么目标为move-1, 如果剩余2步, 则目标为move-1
                    if (move_index - _player_pos_now == 1) step_to_goldbox_nearest = move_index + 1 - _player_pos_now;
                    else if (move_index - _player_pos_now > 2)
                    {
                        if (next_goldbox_index - _player_pos_now > _minGoldSteps)
                            step_to_goldbox_nearest = next_goldbox_index - _player_pos_now;
                        else
                            step_to_goldbox_nearest = move_index - 1 - _player_pos_now;
                    }
                    else if (move_index - _player_pos_now == 2) step_to_goldbox_nearest = move_index - 1 - _player_pos_now;
                }
            }
            else
            {
                step_to_goldbox_nearest = next_goldbox_index - _player_pos_now;
            }
            if (step_to_goldbox_nearest > _minGoldSteps) return 0;
            // 只要大于等于2步, 就用1金2步,  如果剩下1步, 就用2金1步
            //0=随机, 1=2金币只走一点, 2=1金币只走2点
            if (step_to_goldbox_nearest >= 2)
            {
                if (gold_available >= 1) return 2;
                else return 0;
            }
            if (step_to_goldbox_nearest == 1)
            {
                if (gold_available >= 2) return 1;
                else return 0;
            }
            return 0;
        }
        protected void renderGrids(ILogger logger, XmlDocument xml, List<GameGrid> _grids)
        {
            _grids.Clear();
            string gold_box_position = "";
            string free_box_position = "";
            string tree_position = "";
            string ticket_position = "";
            XmlNodeList grid_nodes = xml.SelectNodes("/results/grid");
            foreach (XmlNode grid_node in grid_nodes)
            {
                GameGrid grid = new GameGrid();
                XmlNodeList child_nodes = grid_node.ChildNodes;
                foreach (XmlNode child in child_nodes)
                {
                    if (child.Name == "pos") grid.pos = Int32.Parse(child.InnerText);
                    else if (child.Name == "name") grid.name = child.InnerText;
                    else if (child.Name == "star") grid.star = Int32.Parse(child.InnerText);
                    else if (child.Name == "info") grid.info = child.InnerText;
                }
                _grids.Add(grid);
                if (grid.info.Equals("goldbox")) gold_box_position += grid.pos + ",";
                else if (grid.info.Equals("box")) free_box_position += grid.pos + ",";
                else if (grid.info.Equals("tree")) tree_position += grid.pos + ",";
                else if (grid.info.Equals("ticket")) ticket_position += grid.pos + ",";
            }
            string info = String.Format("金宝箱位置在: [{0}], 免费宝箱位置在: [{1}]", gold_box_position, free_box_position);
            if(tree_position.Length > 0) info += String.Format(", 摇钱树位置在:[{0}]", tree_position);
            if(ticket_position.Length > 0) info += String.Format(", 超级门票在:[{0}]", ticket_position);
            logInfo(logger, info);
        }
        protected void initQuestionDb()
        {
            _question_db.Clear();
            _question_db.Add(new Question("玩家刚进入游戏是什么剧情？", "桃园结义", "黄巾起义", 2));
            _question_db.Add(new Question("什么阵形增加战法伤害", "锋矢阵", "鱼鳞阵", 1));
            _question_db.Add(new Question("多少个麒麟碎片可以合成一个麒麟", "10", "20", 2));
            _question_db.Add(new Question("蜀后主是谁？", "刘封", "刘禅", 2));
            _question_db.Add(new Question("下列谁是“汉初三杰”", "萧何", "曹参", 1));
            _question_db.Add(new Question("科技中的“冲锋”升级会增加____", "战法攻击", "普通攻击", 1));
            _question_db.Add(new Question("人中吕布，马中_____", "追风", "赤兔", 2));
            _question_db.Add(new Question("征收银币在哪里征收的？", "主城", "商店", 1));
            _question_db.Add(new Question("长蛇阵增加_____", "战法伤害", "普通伤害", 2));
            _question_db.Add(new Question("_____之心，路人皆知", "司马昭", "司马懿", 1));
            _question_db.Add(new Question("天公将军是谁", "张宝", "张角", 2));
            _question_db.Add(new Question("玩家可以通过____进入收徒界面", "校场", "兵营", 1));
            _question_db.Add(new Question("七步成诗的是谁", "曹丕", "曹植", 2));
            _question_db.Add(new Question("兵力不足后需要使用什么补足兵力？", "银币", "军功", 1));
            _question_db.Add(new Question("提升税收百分比是什么建筑", "账房", "主城", 1));

            _question_db.Add(new Question("游戏中总共有几种阵形", "8种", "10种", 1));
            _question_db.Add(new Question("张飞的武器是", "丈八蛇矛", "雌雄双股剑", 1));
            _question_db.Add(new Question("刘备托孤是在哪", "成都", "白帝城", 2));
            _question_db.Add(new Question("蜀中无大将，_____为先锋", "廖化", "关平", 1));
            _question_db.Add(new Question("提升税收百分比是什么建筑", "账房", "主城", 1));

            _question_db.Add(new Question("可以用_____训练武将", "军令", "突飞令", 2));
            _question_db.Add(new Question("官渡之战的胜利者是？", "袁绍", "曹操", 2));
            _question_db.Add(new Question("秦始皇是____", "嬴政", "异人", 1));
            _question_db.Add(new Question("败走麦城的是谁", "关羽", "张飞", 1));
            _question_db.Add(new Question("刘关张是在哪里桃园结义的？", "涿县", "长安", 1));
            _question_db.Add(new Question("汉高祖是____", "刘备", "刘邦", 2));
            _question_db.Add(new Question("下列谁不是五虎上将", "魏延", "黄忠", 1));

            _question_db.Add(new Question("诸葛亮出山时是多少岁", "37岁", "27岁", 2));
            _question_db.Add(new Question("军机处可以用来", "升级科技", "征兵", 1));
            _question_db.Add(new Question("军令多久恢复一个？", "半个小时", "一个小时", 2));
            _question_db.Add(new Question("曹操字____", "孟德", "玄德", 1));
            _question_db.Add(new Question("提升征收时获取金币的概率是什么建筑", "主城", "铸币厂", 2));
            _question_db.Add(new Question("祭祀神农能获得____", "金币", "银币", 2));
            _question_db.Add(new Question("项庄舞剑，意在____", "沛公", "刘备", 1));
            _question_db.Add(new Question("威震逍遥津的是魏国哪位武将", "于禁", "张辽", 2));
        }
        protected class TGame
        {
            //<game>
            //    <tid>2</tid>
            //    <armyname>龙且</armyname>
            //    <powername>楚霸王</powername>
            //    <coppercost>200000</coppercost>
            //    <open>1</open>
            //    <maxpos>19</maxpos>
            //    <pos>0</pos>
            //</game>
            public int tid;
            public string powername;
            public int coppercost;
            public int open;
            public int maxpos;
            public int pos;
        }
        protected class GameGrid
        {
            //<grid>
            //    <pos>1</pos>
            //    <name>盗匪袭击</name>
            //    <tips><![CDATA[盗匪：“外来人，要想进古城，留下金币和女人！”]]></tips>
            //    <star>0</star>
            //    <info>battle</info>
            //    <info2><![CDATA[古城城门口总是有些盗匪会向外乡人下手获取财物，你们要小心。<br>战胜盗匪，获得]]></info2>
            //    <pic>battle</pic>
            //</grid>
            public int pos;
            public string name;
            public int star;
            /// <summary>
            /// battle=打架获得东西, box=直接打开宝箱, goldbox=金币打开宝箱, 
            /// punish=花费银币安置流民或者花费兵力应付瘟疫
            /// times=增加纺织次数或者通商次数,
            /// question=回答问题获取奖励
            /// move=前进几格, fin=终点
            /// tree=摇钱树
            /// ticket=超级门票
            /// </summary>
            public string info;
        }
        protected class Question
        {
            public Question(string q, string a1, string a2, int ans)
            {
                question = q; answer1 = a1; answer2 = a2; answer = ans;
            }
            public string question;
            public string answer1;
            public string answer2;
            public int answer;
        }
        #endregion

        #endregion

        #region festival event
        /// <summary>
        /// 0=success, 1=http error, 10=cmd error
        /// </summary>
        /// <returns></returns>
        public int handleFestivalEventInfo(ProtocolMgr protocol, ILogger logger)
        {
            int _fete = 0, _impose = 0, _attack = 0, _feteneed = 0, _imposeneed = 0, _attackneed = 0;
            string url = "/root/festaval!getFestavalNianHuoNew.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "获取迎军活动信息");
            if (result == null) return 1;
            if (!result.CmdSucceed) return 10;
            XmlDocument xml = result.CmdResult;

            //<results>
            //  <state>1</state>
            //  <nianhuoevent>
            //      <starttime>2014-01-29 00:00:00</starttime>
            //      <endtime>2014-01-31 00:00:00</endtime>
            //      <fete>83</fete>
            //      <impose>18</impose>
            //      <attack>28</attack>
            //      <nianhuo>1</nianhuo>
            //      <title>0</title>
            //      <titlecost>20</titlecost>
            //      <feteneed>3</feteneed>
            //      <imposeneed>2</imposeneed>
            //      <attackneed>1</attackneed>
            //  </nianhuoevent>
            //</results>

            XmlNode fete_node = xml.SelectSingleNode("/results/nianhuoevent/fete");
            if (fete_node != null) Int32.TryParse(fete_node.InnerText, out _fete);
            else _fete = 0;

            XmlNode impose_node = xml.SelectSingleNode("/results/nianhuoevent/impose");
            if (impose_node != null) Int32.TryParse(impose_node.InnerText, out _impose);
            else _impose = 0;

            XmlNode attack_node = xml.SelectSingleNode("/results/nianhuoevent/attack");
            if (attack_node != null) Int32.TryParse(attack_node.InnerText, out _attack);
            else _attack = 0;

            XmlNode feteneed_node = xml.SelectSingleNode("/results/nianhuoevent/feteneed");
            if (feteneed_node != null) Int32.TryParse(feteneed_node.InnerText, out _feteneed);
            else _feteneed = 0;

            XmlNode imposeneed_node = xml.SelectSingleNode("/results/nianhuoevent/imposeneed");
            if (imposeneed_node != null) Int32.TryParse(imposeneed_node.InnerText, out _imposeneed);
            else _imposeneed = 0;

            XmlNode attackneed_node = xml.SelectSingleNode("/results/nianhuoevent/attackneed");
            if (attackneed_node != null) Int32.TryParse(attackneed_node.InnerText, out _attackneed);
            else _attackneed = 0;

            while (_fete >= _feteneed && _impose >= _imposeneed && _attack >= _attackneed)
            {
                deliverNianHuo(protocol, logger, ref _fete, ref _impose, ref _attack);
            }
            return 0;
        }
        public int deliverNianHuo(ProtocolMgr protocol, ILogger logger, ref int _fete, ref int _impose, ref int _attack)
        {
            string url = "/root/festaval!deliverNianHuoNew.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "上交年货");
            if (result == null) return 1;
            if (!result.CmdSucceed) return 2;
            XmlDocument xml = result.CmdResult;

            //<results>
            //  <state>1</state>
            //  <color>3</color>
            //  <nianhuoevent>
            //      <fete>80</fete>
            //      <impose>16</impose>
            //      <attack>27</attack>
            //      <nianhuo>2</nianhuo>
            //  </nianhuoevent>
            //  <reward>
            //      <baoshi>88</baoshi>
            //      <bowlder>88</bowlder>
            //  </reward>
            //</results>

            XmlNode fete_node = xml.SelectSingleNode("/results/nianhuoevent/fete");
            if (fete_node != null) Int32.TryParse(fete_node.InnerText, out _fete);
            else _fete = 0;

            XmlNode impose_node = xml.SelectSingleNode("/results/nianhuoevent/impose");
            if (impose_node != null) Int32.TryParse(impose_node.InnerText, out _impose);
            else _impose = 0;

            XmlNode attack_node = xml.SelectSingleNode("/results/nianhuoevent/attack");
            if (attack_node != null) Int32.TryParse(attack_node.InnerText, out _attack);
            else _attack = 0;

            XmlNode reward_node = xml.SelectSingleNode("/results/reward");
            if (reward_node != null)
            {
                int gem_count = 0, stone_count = 0;
                XmlNode gem_node = reward_node.SelectSingleNode("baoshi");
                if (gem_node != null) Int32.TryParse(gem_node.InnerText, out gem_count);
                XmlNode stone_node = reward_node.SelectSingleNode("bowlder");
                if (stone_node != null) Int32.TryParse(stone_node.InnerText, out stone_count);
                logInfo(logger, String.Format("上交年货成功, 宝石+{0}, 玉石+{1}", gem_count, stone_count));
            }

            return 0;
        }
        public int eatNianHuo(ProtocolMgr protocol, ILogger logger, int nianhuoId)
        {
            string url = "/root/festaval!eatNianhuoNew.action";
            string data = "nianhuoId=" + nianhuoId;
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "吃掉年货");
            if (result == null) return 1;
            if (!result.CmdSucceed)
            {
                if (result.CmdError.IndexOf("行动力") >= 0) { return 2; }
                else return 3;
            }
            XmlDocument xml = result.CmdResult;
            logInfo(logger, String.Format("吃掉一个年货, 行动力+3"));
            return 0;
        }
        /// <summary>
        /// 0=success, 1=http error, 10=cmd error
        /// </summary>
        /// <param name="protocol"></param>
        /// <param name="logger"></param>
        /// <returns></returns>
        public int handleFestivalEventVisitInfo(ProtocolMgr protocol, ILogger logger)
        {
            string url = "/root/festaval!getFeatavalVisitInfoNew.action";
            com.lover.astd.common.model.ServerResult result = protocol.getXml(url, "获取新年拜年活动信息");
            if (result == null) return 1;
            if (!result.CmdSucceed) return 10;
            XmlDocument xml = result.CmdResult;
            
            //<results>
            //  <state>1</state>
            //  <type>-1</type>
            //  <festaval>0</festaval>
            //  <officerinfos>
            //      <officer>
            //          <playerid>23945</playerid>
            //          <playerlevel>240</playerlevel>
            //          <playername>200级账号</playername>
            //          <cityflag><![CDATA[穷]]></cityflag>
            //          <skin>2</skin>
            //          <cityskin>0</cityskin>
            //          <nation>1</nation>
            //          <visitornot>1</visitornot>
            //          <legionname>牛</legionname>
            //      </officer>
            //  </officerinfos>
            //  <visitinfo>
            //      <starttime>2014-01-31 00:00:00</starttime>
            //      <endtime>2014-02-03 00:00:00</endtime>
            //      <hongbao>11</hongbao>
            //      <hongbaocost>20</hongbaocost>
            //      <baozhu>23</baozhu>
            //      <randomvist>8</randomvist>
            //  </visitinfo>
            //</results>

            int _visitHongbao = 0, _visitBaozhu = 0, _visitCount = 0;
            XmlNode hongbao_node = xml.SelectSingleNode("/results/visitinfo/hongbao");
            if (hongbao_node != null) Int32.TryParse(hongbao_node.InnerText, out _visitHongbao);
            else _visitHongbao = 0;

            XmlNode baozhu_node = xml.SelectSingleNode("/results/visitinfo/baozhu");
            if (baozhu_node != null) Int32.TryParse(baozhu_node.InnerText, out _visitBaozhu);
            else _visitBaozhu = 0;

            XmlNode visitcount_node = xml.SelectSingleNode("/results/visitinfo/randomvist");
            if (visitcount_node != null) Int32.TryParse(visitcount_node.InnerText, out _visitCount);
            else _visitCount = 0;

            XmlNodeList officer_nodes = xml.SelectNodes("/results/officerinfos/officer");
            foreach (XmlNode officer in officer_nodes)
            {
                string pid = "", pname = ""; bool visited = false;
                XmlNodeList childs = officer.ChildNodes;
                foreach (XmlNode child in childs)
                {
                    if (child.Name == "playerid") pid = child.InnerText;
                    else if (child.Name == "playername") pname = child.InnerText;
                    else if (child.Name == "visitornot") visited = child.InnerText == "1";
                }
                if (!visited) visitOfficer(protocol, logger, ref _visitHongbao, ref _visitBaozhu, pid, pname);
            }

            while (_visitCount > 0)
            {
                visitOfficer(protocol, logger, ref _visitHongbao, ref _visitBaozhu, "%2D100");
                _visitCount--;
            }
            while (_visitHongbao > 0)
            {
                openFestavalGift(protocol, logger, 1);
                _visitHongbao--;
            }
            while (_visitBaozhu > 0)
            {
                openFestavalGift(protocol, logger, 2);
                _visitBaozhu--;
            }
            return 0;
        }
        public int visitOfficer(ProtocolMgr protocol, ILogger logger, ref int _visitHongbao, ref int _visitBaozhu, string pid, string pname = "")
        {
            string url = "/root/festaval!festavalVisitNew.action";
            string data = String.Format("toPid={0}&gold=0", pid);
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, "拜年");
            if (result == null) return 1;
            if (!result.CmdSucceed) return 2;
            XmlDocument xml = result.CmdResult;

            //<results>
            //  <state>1</state>
            //  <officer>
            //      <playerid>143</playerid>
            //      <visitornot>1</visitornot>
            //  </officer>
            //  <hongbao>6</hongbao>
            //  <baozhu>12</baozhu>
            //  <reward>
            //      <visithongbao>3</visithongbao>
            //      <visitbaozhu>6</visitbaozhu>
            //  </reward>
            //</results>
            //<results>
            //  <state>1</state>
            //  <hongbao>4</hongbao>
            //  <baozhu>8</baozhu>
            //  <reward>
            //      <visithongbao>1</visithongbao>
            //      <visitbaozhu>2</visitbaozhu>
            //  </reward>
            //  <visitname>本尊</visitname>
            //  <randomvisit>9</randomvisit>
            //</results>

            XmlNode nowhongbao_node = xml.SelectSingleNode("/results/hongbao");
            if (nowhongbao_node != null) Int32.TryParse(nowhongbao_node.InnerText, out _visitHongbao);
            XmlNode nowbaozhu_node = xml.SelectSingleNode("/results/baozhu");
            if (nowbaozhu_node != null) Int32.TryParse(nowbaozhu_node.InnerText, out _visitBaozhu);

            string hongbaocount = "", baozhucount = "";
            XmlNode pname_node = xml.SelectSingleNode("/results/visitname");
            if (pname_node != null) pname = pname_node.InnerText;
            XmlNode hongbao_node = xml.SelectSingleNode("/results/reward/visithongbao");
            if (hongbao_node != null) hongbaocount = hongbao_node.InnerText;
            XmlNode baozhu_node = xml.SelectSingleNode("/results/reward/visitbaozhu");
            if (baozhu_node != null) baozhucount = baozhu_node.InnerText;

            logInfo(logger, String.Format("向[{0}]拜年成功, 获得红包+{1}, 爆竹+{2}", pname, hongbaocount, baozhucount));

            return 0;
        }
        public int openFestavalGift(ProtocolMgr protocol, ILogger logger, int type)
        {
            string url = "/root/festaval!openFestavalGiftNew.action";
            string data = String.Format("type={0}", type);
            string desc = type == 1 ? "打开拜年红包" : "燃放爆竹";
            com.lover.astd.common.model.ServerResult result = protocol.postXml(url, data, desc);
            if (result == null) return 1;
            if (!result.CmdSucceed) return 2;
            XmlDocument xml = result.CmdResult;

            //<results> 打开拜年红包
            //  <state>1</state>
            //  <ticket>2888</ticket>
            //  <hongbao>10</hongbao>
            //  <color>3</color>
            //</results>
            //<results> 燃放爆竹
            //  <state>1</state>
            //  <baoshi>58</baoshi>
            //  <bowlder>58</bowlder>
            //  <color>1</color>
            //  <baozhu>22</baozhu>
            //</results>
            XmlNodeList nodes = xml.SelectSingleNode("/results").ChildNodes;
            desc += ", 获得";
            foreach (XmlNode node in nodes)
            {
                if (node.Name == "ticket") desc += " 点券+" + node.InnerText;
                else if (node.Name == "hongbao") desc += " 红包+" + node.InnerText;
                else if (node.Name == "baoshi") desc += " 宝石+" + node.InnerText;
                else if (node.Name == "bowlder") desc += " 玉石+" + node.InnerText;
            }
            logInfo(logger, desc);
            return 0;
        }
        #endregion
    }
}
